454.四数相加II
leetcode题目链接:https://leetcode.cn/problems/4sum-ii/
leetcode AC记录:
思路:
1.使用map:key记录数组nums1和nums2的和,value记录nums1和nums2的和的次数(不同下标数字相加相同的和属于不同的组合);
2.双层循环遍历nums3和nums4,如果 0-nums3[i]-nums4[j]存在于map中,取value累计入最终结果;
3.循环结束后的结果返回即可;
代码如下:
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> twoArrSumMap = new HashMap<>();
for(int i = 0;i < nums1.length;i++) {
for(int j = 0;j < nums2.length;j++) {
int twoSum = nums1[i] + nums2[j];
twoArrSumMap.put(twoSum, twoArrSumMap.getOrDefault(twoSum, 0) + 1);
}
}
int count = 0;
for(int i = 0;i < nums3.length;i++) {
for(int j = 0;j < nums4.length;j++) {
int otherTwoSum = nums3[i] + nums4[j];
Integer twoSumCount = twoArrSumMap.get(0 - otherTwoSum);
if(twoSumCount != null) {
count += twoSumCount;
}
}
}
return count;
}
383. 赎金信
leetcode题目链接:https://leetcode.cn/problems/ransom-note
leetcode AC记录:
思路:
1.用map记录magazine数组中字符出现的次数;
2.遍历ransomNote的字符,从map中取字符对应的次数,如果小于等于0,返回false,如果大于0,减1并放回;
代码如下:
public boolean canConstruct(String ransomNote, String magazine) {
Map<Character, Integer> map = new HashMap<>();
for(int i = 0;i < magazine.length();i++) {
char c = magazine.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
for(int i = 0;i < ransomNote.length();i++) {
int num = map.getOrDefault(ransomNote.charAt(i), 0);
if(num <= 0){
return false;
}
map.put(ransomNote.charAt(i), num - 1);
}
return true;
}
15. 三数之和
leetcode题目链接:https://leetcode.cn/problems/3sum
leetcode AC记录:
思路:排序后双指针
1.排序;
2.固定一个下标i不动,如果目标值比当前左右指针、下标i所在数字加和大,右指针向左移动;如果目标值比当前和小,左指针向右移动;
3.去重:如果i和i-1所指数字相同,跳过循环;如果left和left-1所指数字相同,跳过;如果right和right+1指向的数字相同,跳过;
代码如下:
if(nums.length < 3) {
return new ArrayList<>(0);
}
//排序
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
int left,right;
for(int i = 0;i < nums.length;i++) {
if(i > 0 && nums[i] == nums[i-1]) {
continue;
}
left = i + 1;
right = nums.length -1;
while(left < right) {
if(right < nums.length - 1 && nums[right] == nums[right+1]) {
right--;
}else if(nums[i] + nums[left] + nums[right] == 0) {
List<Integer> list = Arrays.asList(nums[i], nums[left],nums[right]);
left++;
right--;
res.add(list);
} else if(nums[i] + nums[left] + nums[right] > 0) {
right--;
} else {
left++;
}
}
}
return res;
}
18. 四数之和
leetcode题目链接:https://leetcode.cn/problems/4sum/submissions
leetcode AC记录:
思路:
1. 相比3数之和,多了一层循环;
2. 去重逻辑一致;
代码如下:
public List<List<Integer>> fourSum(int[] nums, int target) {
if(nums.length < 4) {
return new ArrayList<>(0);
}
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int left,right;
for(int i = 0;i < nums.length;i++) {
if(i > 0 && nums[i-1] == nums[i]) {
continue;
}
for(int j = i + 1;j < nums.length;j++) {
if(j > i + 1 && nums[j-1] == nums[j]) {
continue;
}
left = j + 1;
right = nums.length - 1;
while(left < right) {
long sum = (long)nums[i] + (long)nums[j] + (long)nums[left] + (long)nums[right];
if(left > j + 1 && nums[left] == nums[left-1]) {
left++;
}else if(right < nums.length - 1 && nums[right] == nums[right+1]) {
right--;
}else if(target == sum) {
List<Integer> list = Arrays.asList(nums[i], nums[j], nums[left], nums[right]);
res.add(list);
left++;
right--;
} else if(target < sum){
right--;
} else {
left++;
}
}
}
}
return res;
}