• 4Sum


    Given an array S of n integers, are there elements abc, and d in S such that a + b + c + 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)

    这题的难点在于面向接口编程。 那个 声明 result 的方法很考究。
    1 List<List<Integer>> test = new ArrayList<List<Integer>>();
    2 List<Integer> row = new ArrayList<Integer>();
    3 test.add(row);


     1 public class Solution {
     2     public List<List<Integer>> fourSum(int[] num, int target) {
     3         List<List<Integer>> result = new ArrayList<List<Integer>>();
     4         if(num == null || num.length < 4) return result;
     5         Arrays.sort(num);
     6         int len = num.length;
     7         for(int a = 0; a < len - 3; a ++){
     8             if(a == 0 || num[a] != num[a - 1]){
     9                 for(int b = a + 1; b < len - 2; b ++){
    10                     if(b == a + 1 || num[b] != num[b - 1]){
    11                         int c = b + 1, d = len - 1;
    12                         int goal = target - num[a] - num[b];
    13                         while(c < d){
    14                             if(num[c] + num[d] < goal) c ++;
    15                             else if(num[c] + num[d] > goal) d--;
    16                             else{
    17                                 ArrayList<Integer> row = new ArrayList<Integer>();
    18                                 row.add(num[a]);
    19                                 row.add(num[b]);
    20                                 row.add(num[c]);
    21                                 row.add(num[d]);
    22                                 result.add(row);
    23                                 int cc = num[c], dd = num[d];
    24                                 while(c < d && num[c] == cc) c ++;
    25                                 while(c < d && num[d] == dd) d --;
    26                             } 
    27                         }
    28                     }
    29                 }
    30             }
    31         }
    32         return result;
    33     }
    34 }

     n^2 的算法:

    4sum的hash算法:

    O(N^2)把所有pair存入hash表,并且每个hash值下面可以跟一个list做成map, map[hashvalue] = list,每个list中的元素就是一个pair, 这个pair的和就是这个hash值,那么接下来求4sum就变成了在所有的pair value中求 2sum,这个就成了线性算法了,注意这里的线性又是针对pair数量(N^2)的线性,所以整体上这个算法是O(N^2),而且因为我们挂了list, 所以只要符合4sum的我们都可以找到对应的是哪四个数字。

     1 public class Solution {
     2     public List<List<Integer>> fourSum(int[] num, int target) {
     3         ArrayList<List<Integer>> result = new ArrayList<List<Integer>> ();
     4         if(num == null || num.length < 4) return result;
     5         Arrays.sort(num);
     6         HashMap<Integer, ArrayList<Integer[]>> pair = new HashMap<Integer, ArrayList<Integer[]>> ();
     7         for(int i = 0; i < num.length; i ++){
     8             if(i == 0 || num[i] != num[i - 1]){
     9                 for(int j = i + 1; j < num.length; j ++){
    10                     if(j == i + 1 || num[j] != num[j - 1]){
    11                         Integer sum = num[i] + num[j];
    12                         if(pair.containsKey(sum)) pair.get(sum).add(new Integer[]{num[i], num[j]});
    13                         else {
    14                             ArrayList<Integer[]> list = new ArrayList<Integer[]> ();
    15                             list.add(new Integer[]{num[i], num[j]});
    16                             pair.put(sum, list);
    17                         }
    18                     }
    19                 }
    20             }
    21         }
    22         
    23         HashMap<Integer, Integer> maxAppear = new HashMap<Integer, Integer>();
    24         for(int i = 0; i < num.length; i ++){
    25             if(maxAppear.containsKey(num[i])) maxAppear.put(num[i], maxAppear.get(num[i]) + 1);
    26             else maxAppear.put(num[i], 1);
    27         }
    28         
    29         HashSet<Integer> resultSet = new HashSet<Integer>();
    30         
    31         Iterator point = pair.entrySet().iterator();
    32         while(point.hasNext()){
    33             Map.Entry pairs = (Map.Entry)point.next();
    34             Integer goal = target - (int)pairs.getKey();
    35             if(pair.containsKey(goal)){
    36                 ArrayList<Integer[]> right = pair.get(goal);
    37                 ArrayList<Integer[]> left = (ArrayList<Integer[]>)pairs.getValue();
    38                 for(int i = 0; i < left.size(); i ++){
    39                     for(int j = 0; j < right.size(); j ++){
    40                         int[] row = isValidList(left.get(i), right.get(j),new HashMap<Integer, Integer>(maxAppear));
    41                         if(row != null){
    42                             int rowValue = ((row[0] * 31 + row[1]) * 31 + row[2]) * 31 + row[3];
    43                             if(!resultSet.contains(rowValue)){
    44                                 ArrayList<Integer> oneRow = new ArrayList<Integer>();
    45                                 oneRow.add(row[0]);
    46                                 oneRow.add(row[1]);
    47                                 oneRow.add(row[2]);
    48                                 oneRow.add(row[3]);
    49                                 result.add(oneRow);
    50                                 resultSet.add(rowValue);
    51                             }
    52                         }
    53                     }
    54                 }
    55             }
    56         }
    57         return result;
    58     }
    59     
    60     public int[] isValidList(Integer[] first, Integer[] second, HashMap<Integer, Integer> maxAppear){
    61         if(first[1] > second[0]) return (int[]) null;
    62         int[] result = new int[4];
    63         result[0] = first[0];
    64         result[1] = first[1];
    65         result[2] = second[0];
    66         result[3] = second[1];
    67         for(int i = 0; i < 4; i ++){
    68             if(maxAppear.containsKey(result[i]) && maxAppear.get(result[i]) > 0) maxAppear.put(result[i], maxAppear.get(result[i]) - 1);
    69             else return (int[]) null;
    70         }
    71         return result;
    72     }
    73 }

    迭代器(Iterator)

      迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

      Java中的Iterator功能比较简单,并且只能单向移动:

      (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

      (2) 使用next()获得序列中的下一个元素。

      (3) 使用hasNext()检查序列中是否还有元素。

      (4) 使用remove()将迭代器新返回的元素删除。

      Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

    迭代器应用:
     list l = new ArrayList();
     l.add("aa");
     l.add("bb");
     l.add("cc");
     for (Iterator iter = l.iterator(); iter.hasNext();) {
      String str = (String)iter.next();
      System.out.println(str);
     }
     /*迭代器用于while循环
     Iterator iter = l.iterator();
     while(iter.hasNext()){
      String str = (String) iter.next();
      System.out.println(str);
     }
     */

  • 相关阅读:
    framework7 底部弹层popup js关闭方法
    div动画旋转效果
    面试题3
    面试题2
    CORS跨域请求[简单请求与复杂请求]
    面试题1
    nginx
    Pycharm配置支持vue语法
    Ajax在jQuery中的应用---加载异步数据
    jQuery开发入门
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/3892064.html
Copyright © 2020-2023  润新知