lintcode57 - 3sum - medium

Posted jasminemzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lintcode57 - 3sum - medium相关的知识,希望对你有一定的参考价值。

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.
Example
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is:
(-1, 0, 1)
(-1, -1, 2)
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.

 

注意该问题的2sum部分不要用hashSet的方法,而要用双指针的办法,因为试过后发现前者很难处理重复元素的问题elegantly,比如0,0,0,2,-1,-1的case.

1.主函数内pinned数去重,2sum函数内双指针都去重。方法都是每轮都先check一下指针所指不和上一个数相同,如果是首数例外。
2.记得排序。

 

1.我的实现

public class Solution {
    /**
     * @param numbers: Give an array numbers of n integer
     * @return: Find all unique triplets in the array which gives the sum of zero.
     */
    public List<List<Integer>> threeSum(int[] numbers) {
        // write your code here
        List<List<Integer>> result = new ArrayList<>();
        if (numbers == null || numbers.length == 0) {
            return result;
        }
        
        Arrays.sort(numbers);
        for (int i = 0; i < numbers.length - 2; i++) {
            if (i > 0 && numbers[i] == numbers[i - 1]) {
                continue;
            }
            twoSum(numbers, i + 1, numbers.length - 1, -numbers[i], result);
        }
        return result;
    }
    
    private void twoSum(int[] numbers, int start, int end, int target, List<List<Integer>> result) {
        
        int l = start, r = end;
        while (l < r) {
            while (l < r && l > start && numbers[l] == numbers[l - 1]) {
                l++;
            }
            while (l < r && r < end && numbers[r] == numbers[r + 1]) {
                r--;
            }
            if (l == r) {
                break;
            }
            if (numbers[l] + numbers[r] == target) {
                List<Integer> newItem = new ArrayList<>();
                newItem.add(-target);
                newItem.add(numbers[l]);
                newItem.add(numbers[r]);
                result.add(newItem);
                l++;
                r--;
            } else if (numbers[l] + numbers[r] < target) {
                l++;
            } else {
                r--;
            }
        }
    } 
}

 

2.九章实现

public class Solution {
    /**
     * @param nums : Give an array numbers of n integer
     * @return : Find all unique triplets in the array which gives the sum of zero.
     */
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> results = new ArrayList<>();
        
        if (nums == null || nums.length < 3) {
            return results;
        }
        
        Arrays.sort(nums);

        for (int i = 0; i < nums.length - 2; i++) {
            // skip duplicate triples with the same first numebr
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            int left = i + 1, right = nums.length - 1;
            int target = -nums[i];
            
            twoSum(nums, left, right, target, results);
        }
        
        return results;
    }
    
    public void twoSum(int[] nums,
                       int left,
                       int right,
                       int target,
                       List<List<Integer>> results) {
        while (left < right) {
            if (nums[left] + nums[right] == target) {
                ArrayList<Integer> triple = new ArrayList<>();
                triple.add(-target);
                triple.add(nums[left]);
                triple.add(nums[right]);
                results.add(triple);
                
                left++;
                right--;
                // skip duplicate pairs with the same left
                while (left < right && nums[left] == nums[left - 1]) {
                    left++;
                }
                // skip duplicate pairs with the same right
                while (left < right && nums[right] == nums[right + 1]) {
                    right--;
                }
            } else if (nums[left] + nums[right] < target) {
                left++;
            } else {
                right--;
            }
        }
    }
}

 









以上是关于lintcode57 - 3sum - medium的主要内容,如果未能解决你的问题,请参考以下文章

[LintCode] 3Sum 三数之和

259. 3Sum Smaller小于版3sum

15 & 16. 3Sum & 3Sum Cloest

[Leetcode] 3Sum

3Sum

15. 3Sum