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
  • 相关阅读:
    Net包管理NuGet(3)搭建私服及引用私服的包
    MyMql 下载以及配置
    Oracle 环境部署 以及数据库创建 ,用户新建和权限分配
    VUE.JS 环境配置
    .NET WEB API 简单搭建
    C# Timer 定时任务
    RemoTing 搭建简单实现
    MVC+EF三层+抽象工厂
    ASP.NET MVC SignalR 简单聊天推送笔记
    .net Mvc Dapper 方法封装
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/12875017.html
Copyright © 2011-2022 走看看