zoukankan      html  css  js  c++  java
  • leetcode 15 三数之和

    原题点这里

    取三个数,使和为0,输出所有的组合。各个组合之间不能重复。

    这是个稍微复杂一点的逻辑题。它要求所有的组合不能重复。我们很容易想到三个循环嵌套,分别取三个数,判断加和是否为0,如果为0,判断是否重复。其复杂度为n^3.

    public static List<List<Integer>> threeSum(int[] nums) {
            HashSet<Node15> all = new HashSet<>();
            int n = nums.length;
            List<List<Integer>> ansList=new ArrayList<>();
            int ans = 0;
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    //if(i==j) continue;
    
                    for(int k=j+1;k<n;k++){
                        //if(j==k||i==k) continue;
    
                        if(nums[i]+nums[j]+nums[k]==0){
                            Node15 t = new Node15(nums[i],nums[j],nums[k]);
                            if(all.contains(t)) continue;
                            else
                                all.add(t);
                            System.out.println("=================================");
                           System.out.println(i+":"+nums[i]+"
    "+j+":"+nums[j]+"
    "+k+":"+nums[k]);
                            List<Integer> tmp= new ArrayList<>();
                            tmp.add(i);
                            tmp.add(j);
                            tmp.add(k);
                            ansList.add(tmp);
                            ans++;
                        }
                    }
                }
            }
            //System.out.println(ans);
            return ansList;
        }
    View Code

    这样的话超时了。我们想办法优化一下。

    1 重复组合的去除。我们可以不用set来去除重复项。我们对数据进行排序。然后选择一个开始遍历。选择一个数nums[i],如果nums[i]==nums[i-1],因为我们数组进行过排序,所以这个数字一定是最小值。那么同一个最小值,不重复的组合必须是剩余的两个数不同。所以我们只取一次即可。我们只要保证剩余的两个数,我们只取不同组合即可。我们使用两个指针,l=i+1,r=len-1.分别指向较小的数,和最大值。

    如果 nums[i]+nums[l]+mums[r]=0,这就是一个可选的组合。然后判断,如果nums[l+1]==nums[l],我们跳过nums[l+1],以此类推。对nusm[r]和nums[r-1]也做同样的处理。

    public static List<List<Integer>> threeSum2(int[] nums) {
    
            List<List<Integer>> ansList = new ArrayList<>();
    
            Arrays.sort(nums);
            int len = nums.length;
            for(int i=0;i<len;i++){
                if(nums[i]>0) break;
                if(i>0&&nums[i]==nums[i-1]) continue;
                int l = i+1;
                int r = len-1;
                while(l<r){
                    int ans = nums[i]+nums[l]+nums[r];
                    if(ans==0){
                        ansList.add(Arrays.asList(nums[i],nums[l],nums[r]));
                        while(l<r&&nums[l+1]==nums[l])l++;
                        while(l<r&&nums[r-1]==nums[r])r--;
                        l++;
                        r--;
                    }
                    else if(ans>0) r--;
                    else if(ans<0) l++;
    
                }
            }
    
            //System.out.println(ans);
            return ansList;
        }
    View Code
  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/12875017.html
Copyright © 2011-2022 走看看