zoukankan      html  css  js  c++  java
  • leetcode: 哈希——two-sum,3sum,4sum

     

    1). two-sum

    Given an array of integers, find two numbers such that they add up to a specific target number.

    The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

    You may assume that each input would have exactly one solution.

    Input: numbers={2, 7, 11, 15}, target=9
    Output: index1=1, index2=2

    思路一: 暴力搜索,时间复杂度O(n*n);

    思路二:Map  

    public class Solution{
        public int[] twoSum(int[] numbers,int target){
            int len=numbers.length;
            int[] index=new int[2];
            
            HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
            for(int i=0;i<numbers.length;i++){
                if(!map.containsKey(numbers[i]){
                    map.put(target-numbers[i],i);
                }else{
                    index[0]=map.get(numbers[i]);
                    index[1]=i;
                }
            }
            return index;
        }
    }

     

    2). 3sum

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

    Note:

    • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
    • The solution set must not contain duplicate triplets.
        For example, given array S = {-1 0 1 2 -1 -4},
        A solution set is:
        (-1, 0, 1)
        (-1, -1, 2)

     思路一:三重循环,时间复杂度是O(n^3),而且还要处理重复的问题;

     思路二:     

      先升序排序,然后用第一重for循环确定第一个数字。然后在第二重循环里,第二、第三个数字分别从两端往中间扫。如果三个数的sum等于0,得到一组解。如果三个数的sum小于0,说明需要增大,所以第二个数往右移。如果三个数的sum大于0,说明需要减小,所以第三个数往左移。时间复杂度:O(n2)

    注意:

      1、排序之后天然满足non-descending order的要求

      2、为了避免重复,在没有空间要求情况下可以用map,但是也可以跳过重复元素来做。

    public class Solution {  
      
        public List<List<Integer>> threeSum(int[] num) {  
            List<List<Integer>> ret = new ArrayList<List<Integer>>();  
            int len = num.length, tar = 0;  
      
            if (len <= 2)  
                return  ret;  
      
            Arrays.sort(num);  
      
            for (int i = 0; i <= len - 3; i++) {  
                // first number : num[i]  
                int j = i + 1;  // second number  
                int k = len - 1;    // third number  
                while (j < k) {  
                    if (num[i] + num[j] + num[k] < tar) {  
                        ++j;  
                    } else if (num[i] + num[j] + num[k] > tar) {  
                        --k;  
                    } else {  
                        ret.add(Arrays.asList(num[i], num[j], num[k]));  
                        ++j;  
                        --k;  
                        // folowing 3 while can avoid the duplications  
                        while (j < k && num[j] == num[j - 1])  
                            ++j;  
                        while (j < k && num[k] == num[k + 1])  
                            --k;  
                    }  
                }  
                while (i <= len - 3 && num[i] == num[i + 1])  
                    ++i;  
            }  
            return ret;  
      
        }  
    }
    View Code

    3).4sum

    Given an array S of n integers, are there elements abc, and d in S such that a + bc + d = target? Find all unique quadruplets in the array which gives the sum of target.

    Note:

    • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    • The solution set must not contain duplicate quadruplets.
        For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
        A solution set is:
        (-1,  0, 0, 1)
        (-2, -1, 1, 2)
        (-2,  0, 0, 2)

     思路一:跟之前的 2Sum, 3Sum 一样的做法,先排序,再左右夹逼

     思路二: 先求出每两个数的和,放到 HashSet 里,再利用之前的 2Sum 去求。这种算法比较快,复杂度 O(nnlog(n)),不过细节要处理的不少。

    public class Solution {  
        public List<List<Integer>> fourSum(int[] num, int target) {  
            List<List<Integer>> ret = new ArrayList<List<Integer>>();  
            HashMap<Integer, List<Integer[]>> hm = new HashMap<Integer, List<Integer[]>>();  
            int len = num.length;  
      
            Arrays.sort(num);  
            // store pair  
            for (int i = 0; i < len - 1; ++i) {  
                for (int j = i + 1; j < len; ++j) {  
                    int sum = num[i] + num[j];  
                    Integer[] tuple = {num[i], i, num[j], j};  
                    if (!hm.containsKey(sum)) {  
                        hm.put(sum, new ArrayList<Integer[]>());  
                    }  
                    hm.get(sum).add(tuple);  
                }  
            }  
      
            Integer[] keys = hm.keySet().toArray(new Integer[hm.size()]);  
            for (int key : keys) {  
                if (hm.containsKey(key)) {  
                    if (hm.containsKey(target - key)) {  
                        List<Integer[]> first_pairs = hm.get(key);  
                        List<Integer[]> second_pairs = hm.get(target - key);  
      
                        for (int i = 0; i < first_pairs.size(); ++i) {  
                            Integer[] first = first_pairs.get(i);  
                            for (int j = 0; j < second_pairs.size(); ++j) {  
                                Integer[] second = second_pairs.get(j);  
                                // check  
                                if (first[1] != second[1] && first[1] != second[3] &&  
                                        first[3] != second[1] && first[3] != second[3]) {  
                                    List<Integer> ans = Arrays.asList(first[0], first[2], second[0], second[2]);  
                                    Collections.sort(ans);  
                                    if (!ret.contains(ans)) {  
                                        ret.add(ans);  
                                    }  
                                }  
                            }  
                        }  
      
                        hm.remove(key);  
                        hm.remove(target - key);  
                    }  
                }  
            }  
      
            return ret;  
        }  
    }
    View Code

     

     
  • 相关阅读:
    《英文论文写作再也不难了(工具篇),不收藏就找不到了》
    teachable-machine:探索机器学习如何工作,浏览器中实时浏览
    rasa_core:基于机器学习的对话引擎
    DeepMoji:机器学习模型分析情绪, 情感
    TensorFlow LSTM 注意力机制图解
    Fabrik – 在浏览器中协作构建,可视化,设计神经网络
    移动深度学习 Mobile-deep-learning(MDL)
    Serpent.AI
    face-alignment:用 pytorch 实现的 2D 和 3D 人脸对齐库
    ZhuSuan 是建立在Tensorflow上的贝叶斯深层学习的 python 库
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/5333803.html
Copyright © 2011-2022 走看看