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

     

     
  • 相关阅读:
    uploadify插件的功能应用
    dropify插件的字符串
    VCC、VDD和VSS
    Bootloader升级方式一————擦、写flash在RAM中运行
    Can DBC文件翻译
    CANdbc编辑器的下载和入门介绍
    CAN协议,系统结构和帧结构
    数据帧
    自动驾驶技术之——无人驾驶中的CAN总线
    can物理信号-----------显性和隐性
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/5333803.html
Copyright © 2011-2022 走看看