0
点赞
收藏
分享

微信扫一扫

LeetCode Top 100 Liked Questions 15.3Sum (Java版; Medium)


​​welcome to my blog​​

LeetCode Top 100 Liked Questions 15.3Sum (Java版; Medium)

题目描述

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? 
Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

绊脚案例

加入了重复组合

输入:
[-2,0,0,2,2]
输出
[[-2,0,2],[-2,0,2]]
预期结果
[[-2,0,2]]

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
int cur,L,R;
for(int i=0; i<n; i++){
if(i-1>=0 && nums[i]==nums[i-1]){
continue;
}
cur = nums[i];
L = i+1;
R = n-1;
int target = -cur;
while(L<R){
int sum = nums[L] + nums[R];
if(sum == target){
List<Integer> al = new ArrayList<>();
al.add(cur);
al.add(nums[L]);
al.add(nums[R]);
list.add(al);
L++;
R--;
while(L<R && nums[L]==nums[L-1]){
L++;
}
while(R>L && nums[R]==nums[R+1]){
R--;
}
}else if(sum > target){
R--;
}else{
L++;
}
}
}
return list;
}
}

第一次做; 先对数组排序; 每次选定一个值, 再用双指针选取另外两个值; 双指针在有序数组中往往比较容易确定移动方向; 本题中有两个地方需要跳过处理过的元素:参照值处理过 或者 另外两个值出现过,见绊脚案例; 注意检查数组索引是否越界

  • 双指针与有序数组
  • 参照值大于0的话就break, 因为参照值是最小的, 不可能再有三个数相加和为0的情况了
  • 出现过

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums==null || nums.length<3)
return res;
Arrays.sort(nums);
int left, right, curr;
for(int i=0; i<nums.length-2; i++){
//initialize; update
left = i+1;
right = nums.length - 1;

//小优化, 最小值大于0的话, 三个数相加一定大于0, 跳出循环
if(nums[i]>0)
break;
//出现过的元素不再进行处理, 之前已经处理过了
if(i>0 && nums[i]==nums[i-1])
continue;

//execute
while(left<right){
curr = nums[i] + nums[left] + nums[right];
if(curr>0)
right--;
else if(curr<0)
left++;
//相同的组合不再加入
else if(left >= i+2 && nums[left]==nums[left-1] && nums[right]==nums[right+1]){
left++;
right--;
continue;
}
else
{
res.add(new ArrayList<Integer>());
res.get(res.size()-1).add(nums[i]);
res.get(res.size()-1).add(nums[left]);
res.get(res.size()-1).add(nums[right]);
//update
left++;
right--;
}
}
}
return res;
}
}

优秀答案; res添加元素时使用了Arrays.asList(); 重复元素的处理都用的while

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
for(int k = 0; k < nums.length - 2; k++){
if(nums[k] > 0) break;
if(k > 0 && nums[k] == nums[k - 1]) continue;
int i = k + 1, j = nums.length - 1;
while(i < j){
int sum = nums[k] + nums[i] + nums[j];
if(sum < 0){
while(i < j && nums[i] == nums[++i]);
} else if (sum > 0) {
while(i < j && nums[j] == nums[--j]);
} else {
res.add(new ArrayList<Integer>(Arrays.asList(nums[k], nums[i], nums[j])));
while(i < j && nums[i] == nums[++i]);
while(i < j && nums[j] == nums[--j]);
}
}
}
return res;
}
}


举报

相关推荐

0 条评论