Problem

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

Notice

Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)

The solution set must not contain duplicate triplets.

Example

For example, given array S = {-1 0 1 2 -1 -4}, A solution set is:

(-1, 0, 1)
(-1, -1, 2)

Note

双指针法:O(n^2)的解法。
遍历第一个到倒数第三个数nums[i],作为三数数列的队首;
nums[i]后面的一个数作为三数数列中的第二个数nums[left]
数组中最后一个数nums[nums.length-1]作为三数数列中的第三个数nums[right]
然后用leftright夹逼找到使三数和为零的三数数列,放入结果数组res
对于这三个数,如果循环的下一个数值和当前数值相等,就跳过以避免res中有相同的解。

Solution

public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] A) {
        ArrayList<ArrayList<Integer>> res = new ArrayList();
        if (A.length < 3) return null;
        Arrays.sort(A);
        for (int i = 0; i <= A.length-3; i++) {
            int left = i+1, right = A.length-1;
            if (i != 0 && A[i] == A[i-1]) continue;
            while (left < right) {
                int sum = A[i]+A[left]+A[right];
                if (sum == 0) {
                    ArrayList<Integer> temp = new ArrayList();
                    temp.add(A[i]);
                    temp.add(A[left]);
                    temp.add(A[right]);
                    res.add(temp);
                    left++;
                    right--;
                    while (left < right && A[left] == A[left-1]) left++;
                    while (left < right && A[right] == A[right+1]) right--;
                }
                else if (sum < 0) left++;
                else right--;
            }
        }
        return res;
    }
}

update 2018-9

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);

        for (int i = 0; i < nums.length-2; i++) {
            if (i == 0 || (i > 0 && nums[i] != nums[i-1])) {
                int sum = 0-nums[i];
                int l = i+1, r = nums.length-1;
                
                while (l < r) {
                    int curSum = nums[l]+nums[r];
                    if (curSum == sum) {
                        res.add(Arrays.asList(nums[i], nums[l++], nums[r--]));
                        while (l < r && nums[l] == nums[l-1]) l++;
                        while (l < r && nums[r] == nums[r+1]) r--;
                    } else if (curSum < sum) {
                        l++;
                    } else {
                        r--;
                    }
                }
                
            }
        }
        return res;
    }
}

linspiration
161 声望53 粉丝