这道题目和三数之和差不多 重点还是二数之和三数之和的理解
解法一:
依旧暴力解法 排序+暴力枚举+利用ser去重 (这个解决法绝对超时)
解法二:
排序+双指针(三数之和)
依次固定一个数a 在a后面的区间内,利用三数之和找到三个数 使三个数的和等于target-a即可

细节问题:不重不漏 (和三数之和那里是一样的)
合理的预期:这道题的难度 半天都不为过
下面是效果图和代码:

java
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//定义一个结果数组
List<List<Integer>> ret = new ArrayList<>();
//排序
Arrays.sort(nums);
int n = nums.length;
//固定一个数a
for(int i = 0;i<n;){
//if(nums[i]>0) break; //小小的优化
//int target01 = -nums[i];
//****************************************************************************** */ //三数之和
for(int j =i+1;j<n;){//固定数b 注意上面已经用过了i 所以这里要用其他的变量
long target02 = (long)target-nums[i]-nums[j];//数据太大可能溢出 用long 还要注意强制类型转换
int left= j+1,right =n-1;
//if(nums[j]>0) break; //小小的优化
while(left<right){
int sum = nums[left]+nums[right];//sum要在while循环内部 要不sum不更新
if(sum>target02) right--;
else if(sum<target02) left++;
else{
ret.add(new ArrayList<Integer>(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[right+1]) right--;
//继续缩小空间查找
left++;//熟练之后 可以写到上面ret开头的语句里面
right--;
}
}
//去重二
j++;
while(j<n-1 &&nums[j-1]==nums[j]) j++;
}
//******************************************************************************************* */
//去重三
i++;
while(i<n &&nums[i-1]==nums[i]) i++;
//ret.add(new ArrayList<Integer>(Arrays.asList(nums[i])));
}
return ret;
}
}
//xiyu20251013&1#1*8
//提交数组的时候 直接交4个
//要注意题目已经定义了target这个结果数
/*去重操作还是差点火候 先去重还是先缩小空间?
先移动指针 不能保证left<right 所以先去重 再缩小空间 力扣上面的测试不够狠 要不这个隐患是会出现 的*/
三数之和的复习:
List<List<Integer>> ret = new ArrayList<>();
ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));


关于去重操作:
先去重还是先缩小空间? 越界风险(left不一定就是小于right了) 可能漏解

while(left<right && nums[left]==nums[left+1]) left++; //注意越界异常
这里的left小于right保证了数组没有越界异常
i++; while(i<n &&nums[i-1]==nums[i]) i++;
为什么需要i++呢 先往前走一步 再回头看看是不是重复了
数组越界异常不是只有超出数组

双指针专题完结![烟花][烟花][烟花]
感谢大家的支持

更多内容还在加载中...........
如有问题欢迎批评指正,祝大家生活愉快、学习顺利!!!