zoukankan      html  css  js  c++  java
  • lintcode57

    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--;
                }
            }
        }
    }
  • 相关阅读:
    sratookit
    转录组测序
    单菌基因组测序常见问题
    微生物测序样本准备方法总结
    Review:Microbiota, metagenome, microbiome傻傻分不清
    扩增子、宏基因组测序问题集锦
    扩增子图表解读8网络图:节点OTU或类Venn比较
    扩增子图片解读7三元图
    扩增子图表解读5火山图:差异OTU的数量及变化规律
    扩增子图表解读6韦恩图:比较组间共有和特有OTU或分类单元
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9557886.html
Copyright © 2011-2022 走看看