• [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 };
  • 相关阅读:
    疑问:遍历器 Iterator 接口和生成器函数 Generator 之间的关系?
    2020-03-05:JSX、透传、函数式组件、createElement渲染函数
    疑问:现代浏览器是如何组织模块的?
    2020-03-04:各种遍历方法的区别和 Iterator 遍历器
    2020-03-04:vue-styled-components
    操作系统学习笔记(十一)-- 文件系统管理(下)
    操作系统学习笔记(十)-- 文件系统管理(上)
    操作系统学习笔记(九)-- 虚拟内存管理
    操作系统学习笔记(八)-- 内存管理
    操作系统学习笔记(七)-- 死锁
  • 原文地址:https://www.cnblogs.com/Liok3187/p/4612161.html
Copyright © 2020-2023  润新知