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);
 }
 */

posted on 2014-08-05 13:19  Step-BY-Step  阅读(224)  评论(0编辑  收藏  举报

导航