两数之和
public List<List<Integer>> twoSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int l = 0;
int r = nums.length - 1;
while (l < r) {
if (nums[l] + nums[r] == target) {
res.add(Arrays.asList(nums[l],nums[r]));
while (l < r && nums[l] == nums[l+1]) l++;
while (l < r && nums[r] == nums[r-1]) r--;
l++;
r--;
}else if (nums[l] + nums[r] > target) {
while (l < r && nums[r] == nums[r-1]) r--;
r--;
}else {
while (l < r && nums[l] == nums[l+1]) l++;
l++;
}
}
return res;
}
三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路
三个指针 i, l,r,固定i以后可以转化为二数求和,但注意要跳过三个的重复值
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums); //必须要有序
for (int i = 0; i < nums.length - 2 && nums[i] <= 0; i++) {
if(i == 0 || nums[i] > nums[i - 1]){ //跳过 i 的重复值
int l = i + 1;
int r = nums.length -1;
while (l < r) {
if (nums[l] + nums[r] == -nums[i]) {
res.add(Arrays.asList(nums[i],nums[l],nums[r])); //Arrays.asList()将数组转成List
while (l < r && nums[l] == nums[l+1]) l++; //跳过 l 重复值,下面l和r做了变化,会引起l>=r出现所以条件最好都写上 l < r
while (l < r && nums[r] == nums[r-1]) r--; //跳过 r 重复值
l++;
r--;
}else if (nums[l] + nums[r] > -nums[i]) { //说明得到的和太大了,要减小,此时r--
while (l < r && nums[r] == nums[r-1]) r--; //跳过 l 重复值
r--;
} else {
while (l < r && nums[l] == nums[l+1]) l++; //跳过 r 重复值
l++;
}
}
}
}
return res;
}