zoukankan      html  css  js  c++  java
  • LeetCode:三数之和【15】

    LeetCode:三数之和【15】

    题目描述

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]

    题目分析

    我试了很多方法尝试去解决这个问题,但是都无果。后来在一次算法课上讲到了这个问题,3Sum问题,当时讨论出的解决方法如下:

    List<List<Integer>> mylist = new ArrayList<>();
                Arrays.sort(nums);
                for(int i=0;i<nums.length;i++) {
                    for (int j = i+1;j<nums.length;j++) {
                        int k=Arrays.binarySearch(nums,-(nums[i]+nums[j]));
                        if(k>j)
                        {
                            ArrayList<Integer> al = new ArrayList<>();
                            al.add(nums[i]);al.add(nums[j]);al.add(nums[k]);
                            if(!mylist.contains(al))
                                mylist.add(al);
                        }
                    }
                }
                return mylist;
    }

    当时我对这个结局方案非常满意,可是现在不这么认为了。如果给出的数组是[0,0,0,0],那么就无法解决。

    因为第三个值为0,无论如何到找到的都是中间那个,K不可能大于J。何况J还在自增。但是无论如何这是我们思考后的东西,都是有价值的。

    Java题解

        public List<List<Integer>> threeSum(int[] nums) {
            /*
                思路:从数组序列0开始依次取数作为第一个数字,剩下的两个数字指针从 数组的序列两端开始 相向取数字
                        并且每次都计算3个数的和,如为0则添加到列表,不为0,则根据和的大小,分别移动左右指针。
            
            */
            List<List<Integer>> result = new ArrayList<>();
            if(nums.length < 3) return result;
            Arrays.sort(nums);
            int i = 0;
            while(i < nums.length - 2) { 
                if(nums[i] > 0) break;
                
                int j = i + 1; //左指针
                int k = nums.length - 1; //右指针
                
                while(j < k) {
                    int sum = nums[i] + nums[j] + nums[k];
                    if(sum == 0) result.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    if(sum <= 0) while(nums[j] == nums[++j] && j < k); //实现越过重复数字的功能
                    if(sum >= 0) while(nums[k--] == nums[k] && j < k); //同样实现越过重复数字的功能
                }
                
                while(nums[i] == nums[++i] && i < nums.length - 2);//同上
            }
            return result;
        }

    反思

      1.对 while循环的进一步理解:

        while(nums[i]=nums[++j]&&j<k)

         根据这条命令即可实现越过重复数字的功能.

      2.双指针技术的应用。   

  • 相关阅读:
    23
    关系数据库范式
    组合
    排列
    bfs_迷宫求最短路径
    dfs-求连通块
    dfs_部分和问题
    线程
    http://m.blog.csdn.net/article/details?id=51699295
    jquery 页面多个倒计时
  • 原文地址:https://www.cnblogs.com/MrSaver/p/5913336.html
Copyright © 2011-2022 走看看