LeetCode 15. 3Sum(三数之和)

来源:互联网 发布:网络交友的弊端三条 编辑:程序博客网 时间:2024/04/29 20:40

原题网址:https://leetcode.com/problems/3sum/

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

Note:

  • 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.

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

方法:应用两数之和。

public class Solution {    private Set<String> founded = new HashSet<>();    private String arrayToString(int[] nums) {        String str = "[";        for(int i=0; i<nums.length; i++) {            if (i>0) str += ", ";            str += nums[i];        }        str += "]";        return str;    }    private int[] sort(int[] nums, int from, int to) {        if (from > to || from < 0 || to >= nums.length) return new int[0];        int[] result = new int[to-from+1];        if (from == to) {            result[0] = nums[from];            // System.out.printf("merge sort, before=%s, after=%s, from %d to %d\n", arrayToString(nums), arrayToString(result), from, to);            return result;        }        int mid = (from + to) / 2;        int[] s1 = sort(nums, from, mid);        int[] s2 = sort(nums, mid+1, to);        int i = 0, j = 0;        int pos = 0;        while (i < s1.length || j < s2.length) {            if (i >= s1.length) {                result[pos++] = s2[j++];            } else if (j >= s2.length) {                result[pos++] = s1[i++];            } else if (s1[i] <= s2[j]) {                result[pos++] = s1[i++];            } else {                result[pos++] = s2[j++];            }        }        // System.out.printf("merge sort, before=%s, after=%s, from %d to %d\n", arrayToString(nums), arrayToString(result), from, to);        return result;    }    private List<int[]> twoSum(int[] nums, int sum) {        // System.out.printf("nums=%s, sums=%d\n", arrayToString(nums), sum);        int i=0, j=nums.length-1;        List<int[]> result = new ArrayList<>();        while (i < j) {            if (nums[i] + nums[j] < sum) {                i ++;            } else if (nums[i] + nums[j] > sum) {                j --;            } else {                for(int k = j; k > i; k --) {                    if (nums[i] + nums[k] == sum) {                        int[] pair = new int[2];                        pair[0] = nums[i];                        pair[1] = nums[k];                        // System.out.println("nums=" + arrayToString(nums));                        // System.out.printf("i=%d, k=%d\n", i, k);                        // System.out.println("pair=" + arrayToString(pair));                        result.add(pair);                        break;                    } else {                        break;                    }                }                i ++;            }        }        return result;    }    public List<List<Integer>> threeSum(int[] nums) {        int[] sorted = sort(nums, 0, nums.length - 1);        // System.out.println("sorted=" + arrayToString(sorted));        List<List<Integer>> result = new ArrayList<>();        for(int i = 0; i < sorted.length - 2; i ++) {            while (0 < i && i < sorted.length - 1 && sorted[i] == sorted[i-1]) i++;            if (i == sorted.length) break;            int[] twos = new int[sorted.length - i - 1];            for(int j = i + 1; j < sorted.length; j ++ ) twos[j-i-1] = sorted[j];            List<int[]> pairs = twoSum(twos, -sorted[i]);            for(int k = 0; k < pairs.size(); k ++) {                List<Integer> threes = new ArrayList<>();                threes.add(sorted[i]);                threes.add(pairs.get(k)[0]);                threes.add(pairs.get(k)[1]);                String s = threes.toString();                if (this.founded.contains(s)) continue;                result.add(threes);                this.founded.add(s);            }        }        return result;    }}

另一种实现:

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


0 0