[LeetCode] 454. 4Sum II

题:https://leetcode.com/problems/4sum-ii/description/

题目

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

思路

题目大意

解题思路

主要想法,将 数组A,数组B 相加 组成数组 AB。看数组C、D中是否有元素之和 CDsum,-CDsum在数组AB中。
各方法的不同点在于如何判断 CDsum。

方法 1 time O(n3) 会超时

count 为 组合次数,初始化为 0。
将 数组A,数组B 的每个元素 相加 组成数组 AB。遍历数组C、D元素,求和得到 CDsum,逐次查询-CDsum 在AB中出现的次数 t。count += t
time O(n3)

方法 2 time O(n2logn)

将AB排序,-CDsum中出现的次数 t = upperBound(-CDsum) - lowerBound(-CDsum)。count +=1。

方法3 timeO(n2)

将AB存入map中,key为AB value为出现的次数。count += Map.get(-CDsum)。

code

方法 1 time O(n3) 会超时

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        List<Integer> preRes = new ArrayList<>();
        
        for(int i = 0;i<A.length;i++)
            for(int j = 0 ;j<B.length;j++)
                preRes.add(A[i]+B[j]);
        int count = 0 ;
        for(int k = 0;k<C.length;k++)
            for(int p = 0;p<D.length;p++){
                int tmp = -(C[k]+D[p]);
                for(int i = 0;i<preRes.size();i++){
                    if(tmp == preRes.get(i))    count++;
                }
            } 
        return count;
    }
}

方法 2 time O(n2logn)

class Solution {
    public static int lowerBound(int []nums,int l,int r,int target){
        while(l<r){
            int m = (l+r)/2;
            if(nums[m]>=target) r= m;
            else    l = m +1;
        }
        return l;
    }
    public static int upperBound(int []nums ,int l,int r, int target){
        while(l<r){
            int m = (l+r)/2;
            if(nums[m]<=target) l = m+1;
            else    r = m;
        }
        return l;
    }
    
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        int []preResArr = new int[A.length*B.length];
        int t = 0;
        for(int i = 0;i<A.length;i++)
            for(int j = 0 ;j<B.length;j++)
                preResArr[t++] = A[i]+B[j];
        int count = 0 ;
        Arrays.sort(preResArr);
        
        for(int k = 0;k<C.length;k++)
            for(int p = 0;p<D.length;p++){
                int tmp = -(C[k]+D[p]);
                count += Solution.upperBound(preResArr,0,preResArr.length,tmp) -  Solution.lowerBound(preResArr,0,preResArr.length,tmp);
            } 
        return count;
    }
}

方法3 timeO(n2)

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        Map<Integer,Integer> preResMap = new HashMap<>();
        for(int i = 0; i<A.length;i++)
            for(int j = 0; j<B.length; j++){
                int tmp = A[i] + B[j];
                if(!preResMap.containsKey(tmp))  preResMap.put(tmp,1);
                else
                    preResMap.put(tmp,preResMap.get(tmp)+1);
            }
        int count = 0;
        for(int i = 0;i < C.length; i++)
            for(int j = 0;j < D.length;j++){
                int tmp = -(C[i]+D[j]);
                if(preResMap.containsKey(tmp))  count += preResMap.get(tmp);
            }
        return count;
    }
}

猜你喜欢

转载自blog.csdn.net/u013383813/article/details/82939855