The sum of three numbers + 16. The closest sum of three numbers

1, 15. The sum of three numbers

Given a n array nums containing n integers, determine whether there are three elements a, b, c in nums, so that a + b + c = 0? Find out all triples that satisfy the conditions and do not repeat.

Note: The answer should not contain duplicate triples.

For example, given array nums = [-1, 0, 1, 2, -1, -4],

The set of triples satisfying the requirements is:
[
[-1, 0, 1],
[-1, -1, 2]
]

Method 1: Retrospective, timeout

//With backtracking, it's overtime.~~~
    public List<List<Integer>> threeSum1(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        backTrack(nums, res, new ArrayList<Integer>(), 0);
        return res;
    }

    private void backTrack(int[] nums, List<List<Integer>> res, ArrayList<Integer> list, int start) {
        if (list.size() == 3) {
            if (sumList(list) == 0) {
                Collections.sort(list);
                res.add(new ArrayList<>(list));
            } else {
                return;
            }
        } else {
            for (int i = start; i < nums.length; i++) {
                //Notice this: otherwise there are two identical {-1,0,1}
                if (i == start || nums[i] != nums[i - 1]) {
                    list.add(nums[i]);
                    backTrack(nums, res, list, i + 1);
                    list.remove(list.size() - 1);
                }
            }
        }
    }

    private int sumList(ArrayList<Integer> list) {
        return list.get(0) + list.get(1) + list.get(2);
    }

Method 2: The idea is to sort the arrays first, then fix a number (traversal) to get the results.

public List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> res = new ArrayList<>();

        Arrays.sort(nums);
        for (int i = 0; i < nums.length - 2; i++) {
            if (nums[i] > 0)
                return res;

            while (i > 0 && i < nums.length && nums[i] == nums[i - 1])
                i++;

            int j = i + 1;
            int k = nums.length - 1;
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                if (sum == 0) {
                    res.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    //Notice that comparing J < K here is enough
                    while (++j < k && nums[j] == nums[j - 1]) ;
                    //j < - k, first - k, then compare the sizes of j and K
                    while (j < --k && nums[k] == nums[k + 1]) ;
                } else if (sum < 0) {
                    while (++j < k && nums[j] == nums[j - 1]) ;
                } else {
                    while (j < --k && nums[k] == nums[k + 1]) ;
                }
            }
        }
        return res;
    }

2, 16. The closest sum of three numbers

Given an array nums with n integers and a target value. Find out three integers in nums so that they are closest to target. Returns the sum of these three numbers. Assume that only one answer exists for each set of inputs.

For example, given array nums = [-1, 2, 1, - 4], and target = 1.

The sum of the three closest numbers to target is 2. (-1 + 2 + 1 = 2).

public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);

        int closest = nums[0] + nums[1] + nums[2];
        for (int i = 0; i < nums.length - 2; i++) {
            int j = i + 1;
            int k = nums.length - 1;
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                if (sum == target) {
                    return sum;
                } else if (sum < target) {
                    while (++j < k && nums[i] + nums[j] + nums[k] < target) ;
                    if (Math.abs(closest - target) > Math.abs(nums[i] + nums[j - 1] + nums[k] - target))
                        closest = nums[i] + nums[j - 1] + nums[k];
                } else {
                    while (j < --k && nums[i] + nums[j] + nums[k] > target) ;
                    if (Math.abs(closest - target) > Math.abs(nums[i] + nums[j] + nums[k + 1] - target))
                        closest = nums[i] + nums[j] + nums[k + 1];
                }
            }
        }
        return closest;
    }

Posted by rulinus on Tue, 09 Apr 2019 17:06:32 -0700