[LintCode/LeetCode] 3Sum

511 查看

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