- 三數之和
給你一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
示例:
給定數組 nums = [-1, 0, 1, 2, -1, -4],
滿足要求的三元組集合爲:
[
[-1, 0, 1],
[-1, -1, 2]
]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/3sum
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 注意整型超過127後直接 == 會出錯
* Arrays也有對數組的排序函數
**/
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
return graceSolution(nums);
}
public List<List<Integer>> graceSolution(int[] nums) {
// 特殊情況
if (nums == null || nums.length < 3)
return new ArrayList<>();
//排序數組,只有排序後可以利用雙指針移動的方式來達到目標值
List<Integer> numsList = Arrays.stream(nums).boxed().collect(Collectors.toList());
Collections.sort(numsList);
ArrayList<List<Integer>> res = new ArrayList<>();
//如果第一個元素都大於零直接返回空
if (numsList.get(0) > 0) return res;
ArrayList<Integer> temp = null;
//固定i 然後利用R L指針來獲取目標值(盛最多的水)
for(int i = 0; i < numsList.size(); i++) {
int l = i +1;
int r = numsList.size() - 1;
//如果當前元素都大於0了就不可能有結果了
if(numsList.get(i)>0)
return res;
//如果當前元素有重複元素就可以直接跳過
if(i>0 && numsList.get(i).equals(numsList.get(i - 1)))
continue;
while(l < r) {
int curNum = numsList.get(i) + numsList.get(l) + numsList.get(r);
if (curNum == 0) {
temp = new ArrayList<>();
temp.add(numsList.get(i));
temp.add(numsList.get(l));
temp.add(numsList.get(r));
res.add(temp);
//如果當前已經符合要求,那麼當前l和r對應位置的值都不能再使用了,避免重複
while(l < r && numsList.get(l).equals(numsList.get(l + 1)))
l++;
while(l < r && numsList.get(r).equals(numsList.get(r - 1)))
r--;
l++;
r--;
}
else if (curNum > 0) {
// 如果結果大於0, 那麼需要將r--纔可能使得結果減少,因爲目前數組已經排序
r--;
}
else
l++;
}
}
return res;
}
public List<List<Integer>> other(int[] nums) {
List<List<Integer>> lists = new ArrayList<>();
//排序
Arrays.sort(nums);
//雙指針
int len = nums.length;
for(int i = 0;i < len;++i) {
if(nums[i] > 0) return lists;
if(i > 0 && nums[i] == nums[i-1]) continue;
int curr = nums[i];
int L = i+1, R = len-1;
while (L < R) {
int tmp = curr + nums[L] + nums[R];
if(tmp == 0) {
List<Integer> list = new ArrayList<>();
list.add(curr);
list.add(nums[L]);
list.add(nums[R]);
lists.add(list);
while(L < R && nums[L+1] == nums[L]) ++L;
while (L < R && nums[R-1] == nums[R]) --R;
++L;
--R;
} else if(tmp < 0) {
++L;
} else {
--R;
}
}
}
return lists;
}
}