[LeetCode][JavaScript]4Sum

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)

https://leetcode.com/problems/4sum/


我看Tags里有HashTable,想想三重循环根本用不到,就没有用这个解法。

先两两合并,再用双指针去找结果,写了好多好伤心。 

1.合并的结果记入twoSumArr,为了查找再开一个twoSumMap记录下数字的组合。

 以题目中的例子来说,twoSumArr -> [-3, -2, -1, 0, 1, 2, 3] , twoSumMap[0] -> [ [-2, 2], [-1, 1], [0, 0] ]

2.在遍历nums的时候,记下每个数字出现的频率,之后的检查要用到,比如这个结果是不合法的[-2, 1, 0 ,1],1只能用一次。

3.最后用双指针遍历twoSumArr求结果,这时会碰到重复的情况。

比如 -1 + 1 = 0, twoSumMap[-1] -> [ [-2, 1], [-1, 0] ],  twoSumMap[1] -> [ [-1, 2], [0, 1] ]

在遍历中加一个判断,前一个(-1)里较大的那个数,小于后一个(1)里较小的数,才要记录到结果中,这样就可以去重。

还是写个三重循环比较简单粗暴,这个要考虑好多种情况。

 1 /**
 2  * @param {number[]} nums
 3  * @param {number} target
 4  * @return {number[][]}
 5  */
 6 var fourSum = function(nums, target) {
 7     nums = nums.sort(sorting);
 8     var result = [];
 9     var countAppear = {}; twoSumMap = {}, twoSumArr = [];
10     var i, j, twoSum;
11     for(i = 0; i < nums.length; i++){
12         if(!countAppear[nums[i]]){
13             countAppear[nums[i]] = 1;
14         }else{
15             countAppear[nums[i]]++;
16         }
17         for(j = i + 1; j < nums.length; j++){
18             twoSum = nums[i] + nums[j]; 
19             if(!twoSumMap[twoSum]){
20                 twoSumArr.push(twoSum);
21                 twoSumMap[twoSum] = [[nums[i], nums[j]]];
22             }else if(!arrContains(twoSumMap[twoSum], nums[i], nums[j])){
23                 twoSumMap[twoSum].push([nums[i], nums[j]]);
24             }
25         }
26     }
27     twoSumArr = twoSumArr.sort(sorting);
28     
29     var numA, numB, sum4;
30     for(i = 0, j = twoSumArr.length - 1; i <= j;){
31         numA = twoSumMap[twoSumArr[i]], numB = twoSumMap[twoSumArr[j]];
32         sum4 = twoSumArr[i] + twoSumArr[j];
33         if(sum4 === target){
34             addCandidate(numA, numB, result);
35         }
36         if(sum4 < target){
37             i++;
38         }else{
39             j--;
40         }
41     }
42     return result;
43     
44     function verifyResult(arr){
45         var previous = null, count = 0;
46         for(var i = 0; i < arr.length; i++){
47             if(arr[i] !== previous){
48                 previous = arr[i];
49                 count = 1;
50             }else{
51                 count++;
52                 if(count > countAppear[previous]){
53                     return false;
54                 }
55             }
56         }
57         return true;
58     }
59     function addCandidate(numA, numB, result){
60         var i, j, tmp;
61         for(i = 0; i < numA.length; i++){
62             for(j = 0; j < numB.length; j++){
63                 if(numA[i][1] <= numB[j][0]){
64                     tmp = [numA[i][0], numA[i][1], numB[j][0], numB[j][1]];
65                     if(verifyResult(tmp)){
66                         result.push(tmp);
67                     }   
68                 }        
69             }
70         }
71     }
72     function arrContains(arr, small, large){
73         for(var i = 0; i < arr.length; i++){
74             if(arr[i][0] === small && arr[i][1] === large){
75                 return true;
76             }
77         }
78         return false;
79     }
80     function sorting(a, b){
81         if(a > b){
82             return 1;
83         }else if(a < b){
84             return -1;
85         }else{
86             return 0;
87         }
88     }
89 };
原文地址:https://www.cnblogs.com/Liok3187/p/4612161.html