11. <tag-数组和双指针(左右指针)>-lt.18-四数之和 2.8
lt.18-四数之和
[案例需求]
[思路分析]
- 本题也就是三数之和的拓展罢了, 前面我们三数之和怎么解的呢? --> 先对数组排序, 然后共一层for循环遍历第一个加数, 后面两个加数分别使用左指针和右指针向中间(L=R)逼近的方式进行遍历.
- 同样的, 四数之和, 使用两层for循环遍历前两个加数, 使用左右指针遍历后两个加数;
- 像这种数组中, 多个加数的和, 最重要的就是熟练掌握对加数的去重, 因为每个加数都是遍历得到的, 比如第一个加数a, 它(nums[i])和前一次遍历的数(nums[i-1]), 是重复的, 那么必然是要去重的(
因为后面的加数也是靠遍历得到的, 第一个加数重复遍历, 必然会导致得到的一组加数也是重复的
), 同时 i > 0的判断也是必不可少的(防止溢出)
[代码实现]
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//大list套小list
List<List<Integer>> lists = new ArrayList<>();
//先对数组进行排序,外层遍历第一个数, 内层遍历第二个数,
//另外设置两个指针, 指代第三个和第四个加数
//特例
if(nums.length < 4) return lists;
//先对数组进行排序
Arrays.sort(nums);
//左右指针, 分别代表第三个和第四个加数
int L = 0;
int R = 0;
for(int i = 0; i < nums.length-3; i++){
//去重!!!!
if(i > 0 && nums[i] == nums[i - 1]) continue;
//第一个加数
int a = nums[i];
for(int j = i+1; j < nums.length-2; j++){
if( j > i + 1 && nums[j] == nums[j - 1]) continue;
//第二个加数
int b = nums[j];
//第三个和第四个加数的下标
L = j + 1;
R = nums.length - 1;
while(L < R) {
int sumOfFour = a + b + nums[L] + nums[R];
if (sumOfFour < target) {
L++;
} else if (sumOfFour > target) {
R--;
} else {
//还是要去重啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
while(L < R && nums[L + 1] == nums[L]) L++;
while(L < R && nums[R - 1] == nums[R]) R--;
List<Integer> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(nums[L]);
list.add(nums[R]);
lists.add(list);
R--;
L++;
}
}
}
}
return lists;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)