zoukankan      html  css  js  c++  java
  • 15. 3Sum

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

    我看这个解答,一开始反复卡在左边界lo为什么==i+1,说是为了避免重复。

    后来举例子【-4,-3,1,7】,-4能和-3和7成对,到了-3,如果从0开始,就会也形成-4,-3和7,这样就重复了。所以每次左边界都要从i+1开始

    或者这样理解,i是可能解的左下标,lo是中间,hi是右边,所以lo = i + 1

    3sum就是固定一个数,剩下就是一个2sum,但题目要求不能有重复triplets出现,所以需要去重

    具体方法是先对数组排序,i代表合适解的左下表,所以是i < nums.length - 2, 从下标1开始如果和前面重复就continue,然后如果nums[ i ] > 0就break,因为后面数都比他大不可能还有解。

    然后就是具体情况,lo和hi和target设置好,如果lo+hi == target就是一个解,然后左右向中间靠拢,这里也要考虑重复元素,排除重复后更新lo和hi

    最后返回即可。

  • 相关阅读:
    poj3614 Sunscreen 题解报告
    poj2299 Ultra-QuickSort 题解报告
    poj3784 Running Median 题解报告(对顶堆)
    CH103 Cinema 题解报告
    poj1845 Sumdiv 题解报告
    poj2018 Best Cow Fences 题解报告
    $CF311B Cats Transport$ 斜率优化
    斜率优化入门题:任务安排$123$ : )
    $Poj1821 Fence $单调队列优化$DP$
    《算法竞赛》$0×00$基本算法
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/10328976.html
Copyright © 2011-2022 走看看