【探索-中級演算法】三數之和
阿新 • • 發佈:2018-11-03
參考連結:LeetCode總結-K-Sum問題
本文介紹的解題思想的核心就是排序,排序有兩個目的,第一個是次要的,即方便排除重複的組合。第二個就是使得可以按照遞增或者遞減方便的移動指標 l、r
。
在排序之後,就可以對陣列進行遍歷,目標就是找到符合 nums[l] + nums[r] == -target
的組合,而 target
是固定不變的,只要動態的尋找符合條件的 nums[l] 、nums[r]
。
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort( nums);
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) { //跳過相同的數以避免相同組合的產生
//比如在 -1 -1 0 1 2 的 nums 陣列中
// target 為 nums[0] 與 nums[1] 的效果肯定是一樣的
continue ;
}
find(result, nums, i + 1, nums.length - 1, nums[i]);target
}
return result;
}
public void find(List<List<Integer>> result, int[] nums, int start, int end, int target) {
int l = start, r = end;
while (l < r) {
if (target + nums[l] + nums[r] == 0) {
List<Integer> list = new ArrayList<>();
list.add(target);
list.add(nums[l]);
list.add(nums[r]);
result.add(list);
while (l < r && nums[l] == nums[l + 1]) ++l;//跳過相同的數以避免相同組合的產生
while (l < r && nums[r] == nums[r - 1]) --r;//跳過相同的數以避免相同組合的產生
++l;
--r;
} else if (target + nums[l] + nums[r] < 0) {
// nums[l]+nums[r] < -target,因此還需加大 nums[l]+nums[r] 的和
++l;
} else {
// 同上
--r;
}
}
}
需要注意的是,題目中說要避免重複的三元組。