题目
题解
- 先对数组排序再循环,因为排序完当循环到nums[i]>0的时候,后面的无须循环因为最左侧是正数,三个正数的和不可能是0,因为三数之和是nums[i]+nums[i+1]+nums[nums.length - 1]即nums[i]大于0 三数之和不可能为0即退出整个循环break。
- 循环整个数组,i > 0 && nums[i - 1] == nums[i]是为了判断相同的值,发现当前值和前一个值相等直接continue。
- 然后循环while (left < right)循环就是定义左右两个结点加上自己循环的nums[i],我们定死nums[i]让left=nums[i+1]和right=nums[nums.length - 1]两边往中间走。
- 判断当三数之和sum==0返回,当三数之和小于0因为是有序的,肯定是左边的不够大需要left++,反之三数之和大于0就是right太大需要right--
- 再想sum==0的时候因为题意要求不止一组满足sum==0,当sum等于0的时候需要继续往中间走继续找满足的条件,很容易想到直接让left++;和right--再往中间走的时候左右两边遇见重复的直接各自left++和right--去重。
代码
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> array = new ArrayList<>();
if (nums == null || nums.length < 3) {
return array;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i - 1] == nums[i]) {
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int temp = nums[left] + nums[right] + nums[i];
if (temp == 0) {
array.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
left++;
right--;
} else if (temp < 0) {
left++;
} else if (temp > 0) {
right--;
}
}
}
return array;
}
备注
本文正在参与「掘金 2021 春招闯关活动」, 点击查看。