Leetcode 之 4Sum II

来源:互联网 发布:淘宝袜子尺码 编辑:程序博客网 时间:2024/05/16 19:46

题目描述:
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.

To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.

Example:

Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

Output:
2

Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

相比4Sum这道题简单了不少,一开始看错了题目要求,以为要把所有组合都找出来,这样倒是比原题麻烦一点儿,但思路还算简单:
如果是暴力强解,复杂度应该是O(n^4),但咱们可以把A,B和C,D两两组合起来,再去找答案,这样就降低成了O(n^2)
先将A+B的所有组合,保存到一个map里,key是两者的sum,value是index的组合。 C+D一样操作。
再遍历A+B的map的key值,去找C+D的map的key值中有没有 A+B key值的相反数,有的话保存组合到list里。

代码如下:

public List<List<Integer>>fourSumII(int[]A,int[]B,int[]C,int[]D){        List<List<Integer>>L=new ArrayList<List<Integer>>();        List<Integer>l;        HashMap<Integer,HashSet<int[]>>map1=new HashMap<Integer,HashSet<int[]>>(),map2=new HashMap<Integer,HashSet<int[]>>();        HashSet<int[]>set;              int[]temp;        int sum;        for(int i=0;i<A.length;i++){            for(int j=0;j<B.length;j++){                sum=A[i]+B[j];                if(map1.containsKey(sum)){                    set=map1.get(sum);                }                else                    set=new HashSet<int[]>();                temp=new int[2];                temp[0]=i;                temp[1]=j;                set.add(temp);                map1.put(sum, set);            }        }        for(int i=0;i<C.length;i++){            for(int j=0;j<D.length;j++){                sum=C[i]+D[j];                if(map2.containsKey(sum)){                    set=map2.get(sum);                }                else                    set=new HashSet<int[]>();                temp=new int[2];                temp[0]=i;                temp[1]=j;                set.add(temp);                map2.put(sum, set);            }        }        HashSet<int[]>rest;        for(int sum1:map1.keySet()){            if(!map2.containsKey(-sum1))continue;            rest=map2.get(-sum1);            for(int[]h1:map1.get(sum1)){                for(int[]h2:rest){                    l=new ArrayList<Integer>();                    for(int i:h1)l.add(i);                    for(int i:h2)l.add(i);                    L.add(l);                }            }        }        return L;    }

题目的真实要求是找出组合的数目,这样就稍微简单一点了,
A+B,C+D的操作类似上述,但value值保存的是key值对应的个数。
再去遍历,总和等于A+Bmap的key值个数乘以C+Dmap中-key对应的个数。

代码如下:

public int fourSumII2(int[]A,int[]B,int[]C,int[]D){        HashMap<Integer,Integer>m1=new HashMap<Integer,Integer>();        HashMap<Integer,Integer>m2=new HashMap<Integer,Integer>();        int sum=0,times;        for(int i=0;i<A.length;i++){            for(int j=0;j<B.length;j++){                sum=A[i]+B[j];                if(m1.containsKey(sum)){                    times=m1.get(sum);                    times++;                    m1.put(sum, times);                }                else                    m1.put(sum, 1);            }        }               for(int i=0;i<C.length;i++){            for(int j=0;j<D.length;j++){                sum=C[i]+D[j];                if(m2.containsKey(sum)){                    times=m2.get(sum);                    times++;                    m2.put(sum, times);                }                else                    m2.put(sum, 1);            }        }        int total=0;            for(int p1:m1.keySet()){            if(m2.containsKey(-p1)){                total+=m1.get(p1)*m2.get(-p1);            }        }        return total;    }
0 0
原创粉丝点击