文章目录
day07学习内容
day07主要内容
- 四数相加
- 赎金信
- 三数之和
- 四数之和
一、 四数相加
核心思路
1、这道题和异位词那题很像,主要难点在于理清楚map的key和value分别存放什么即可
1.错误写法1
for (int i : nums1) {
我用成了
for(int i=0;i<nums.length;i++)
为什么这么写,说明还是没有理解map的key和value分别代表什么。理解的话,也不会这样写了
2.正确写法1
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer, Integer> map1 = new HashMap<>();
int count = 0;
for (int i : nums1) {
for (int j : nums2) {
map1.put(i + j, map1.getOrDefault(i + j, 0) + 1);
}
}
for (int i : nums3) {
for (int j : nums4) {
count += map1.getOrDefault(0 - (i + j), 0);
}
}
return count;
}
}
二、赎金信
思路
体会一下和有效的异位词的区别吧。
1.正确写法1
略
三、三数之和
1.思路
- 通过一个for循环和双指针的方法求解。
2.去重的细节,究竟是判断i和i+1还是判断i和i-1
eg:nums = [-3,-1,-1,2]
- 如果是判断i和i+1,那么相当于判断结果集是不是有重复元素,不符合题意
- 看下俩图
- 从debug结果看,很明显写成i+1,会导致娶不到正确的结果,跳过了符合题意的结果。
3.正确写法
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
// 排序
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
// 如果第一个数都大于0,那么肯定找不到相加=0的数。因为排过序了,很好理解
if (nums[i] > 0) {
return result;
}
// 对nums[i]去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) {
right--;
}
if (sum < 0) {
left++;
}
// 和为0,说明找到了需要的数
if (sum == 0) {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[left - 1]) {
right--;
}
left++;
right--;
}
}
}
return result;
}
}
四、四数之和
1.思考
核心思路
- 基本上和三数之和差不多的思路
2.正确写法
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
// 排序
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
// 如果第一个数都大于0,并且第一个数大于tartget,那么肯定找不到相加=target的数。
// 此处需要考虑负数的情况
if (nums[i] > 0 && nums[i] > target) {
return result;
}
// 对nums[i]去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < nums.length; j++) {
// 对nums[j]去重
if (j > i + 1 && nums[j - 1] == nums[j]) {
continue;
}
int left = j + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum > target) {
right--;
}
if (sum < target) {
left++;
}
// 和为target,说明找到了需要的数
if (sum == target) {
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[left - 1]) {
right--;
}
left++;
right--;
}
}
}
}
return result;
}
}
总结
1.感想
- 三数之和的思路不知道,看了代码随想录的视频才理解的,看完视频后,自己写了一遍还是报错,看了一眼题解,照着代码写才写对的
- 四数之和,关键体会和三数之和的不同地方
- 今天发版日,比较忙,后面俩天有空再来补充下笔记
2.思维导图
本文思路引用自代码随想录,感谢代码随想录作者。