版权声明:转载请标明出处「OneDeveloper」 https://blog.csdn.net/OneDeveloper/article/details/83308528
参考链接: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;
}
}
}
需要注意的是,题目中说要避免重复的三元组。