zoukankan      html  css  js  c++  java
  • leetcode15 3Sum

    题目内容

    Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

    Note:

    The solution set must not contain duplicate triplets.

    Example:
    Given array nums = [-1, 0, 1, 2, -1, -4],
    
    A solution set is:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    

    分析过程

    • 题目归类:
      数组,遍历,hashmap

    • 题目分析:
      上一篇博客采用hashmap解决了two sum的问题。类似的本题可以采用two sum的方式完成,固定第一个值x,此时另外两个值的和为 0-x;

    • 边界分析:

      • 空值分析
        nums为空返回空
      • 循环边界分析
        循环变量不可以大于nums.length;
    • 方法分析:

      • 数据结构分析
        hashmap,hashmap 的key保存具体数值,value保存index。
        在比较的时候需要设立一个变量保存index,相同的数值,不同index才能使用。

        补充:根据two sum 的方法,当出现两个相同的数和一个其他数相加为0时,会出现重复的情况。例如:[-1,1,0],[-1,-1,2],[0,-1,1]。用这种方法需要去重,
        去重方法;使用hashset就可以判断重复的情况,之前以为hashset中的arraylist是保存的数据的引用,所以new新的arraylist就无法去重。现在看来hashset中equals是通过判断每一个list中的hashcode。
      public int hashCode() {
          int hashCode = 1;
          for (E e : this)//E 为List<E>,this为需要添加的对象(String/ArrayList)
              hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
          return hashCode;
      }
      
      • 状态机
      • 状态转移方程
      • 最优解
    • 测试用例构建
      [1,2,3,-1,-2,-3,0],
      []

    代码实现

    import java.util.*;
    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            HashSet<List<Integer>> set = new HashSet<List<Integer>>();
            List<Integer> tmpList ;
            for(int i = 0;i < nums.length; i++){
                HashMap<Integer,Integer> map = new HashMap<>();
                int target = 0 - nums[i];
                for(int j = i+1; j < nums.length;j++){
                    int value = target - nums[j];
                    if(map.containsKey(value)){
                        tmpList = new ArrayList<Integer>();
                        tmpList.add(nums[i]);
                        tmpList.add(nums[j]);
                        tmpList.add(value);
                        Collections.sort(tmpList);
                        set.add(tmpList);
                        
                    }else{
                        map.put(nums[j],j);
                    }
                    
                }
            }
            return new ArrayList<List<Integer>>(set);
        }
    }
    

    效率提高


    由图可知效率不高。
    学习到另外一种方式可以有效的降低时间复杂度。
    首先先排序。
    设置一个i,j,k,分别为不同的下标。i的值不能大于nums.length-2; j 的值不能大于nums.length-1, k的值不小于等于j
    和之前一样,先固定i的值。之后nums[i],nums[j],nums[k]之和如果大于0,k--,反之j++,当j>=k时break;

    import java.util.*;
    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            HashSet<List<Integer>> set = new HashSet<List<Integer>>();
            Arrays.sort(nums);
            for(int i = 0; i < nums.length-2;i++){
                int j = i+1;
                int k = nums.length-1;
                while(j<k){
                    int sum =nums[i]+nums[j]+nums[k];
                    if(sum==0)
                        set.add(Arrays.asList(nums[i],nums[j++],nums[k--]));
                    else if(sum>0)
                        k--;
                    else if(sum<0)
                        j++;
                }
            }
            return new ArrayList<List<Integer>>(set);
        }
    }
    

    效率依旧不高,但是使用的方法可以借鉴。

    拓展问题

    3Sum Closest
    4Sum
    3Sum Smaller

  • 相关阅读:
    hihoCoder#1128 二分·二分查找
    hihoCoder#1127 二分图三·二分图最小点覆盖和最大独立集
    hihoCoder#1122 二分图二•二分图最大匹配之匈牙利算法
    hihoCoder#1105 题外话·堆
    Ajax详细剖析
    web框架之--Tornado
    web框架之--先来个介绍
    前端之--Jquery-玩穿它!
    前端之--DOM详解应用
    前端之--JavaScript作用域--超细讲解
  • 原文地址:https://www.cnblogs.com/clnsx/p/12240564.html
Copyright © 2011-2022 走看看