[LeetCode][JavaScript]4Sum
2015-07-01 00:18
597 查看
4Sum
Given an array S of n integers, are there elements a, b, c, 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)里较小的数,才要记录到结果中,这样就可以去重。
还是写个三重循环比较简单粗暴,这个要考虑好多种情况。
/** * @param {number[]} nums * @param {number} target * @return {number[][]} */ var fourSum = function(nums, target) { nums = nums.sort(sorting); var result = []; var countAppear = {}; twoSumMap = {}, twoSumArr = []; var i, j, twoSum; for(i = 0; i < nums.length; i++){ if(!countAppear[nums[i]]){ countAppear[nums[i]] = 1; }else{ countAppear[nums[i]]++; } for(j = i + 1; j < nums.length; j++){ twoSum = nums[i] + nums[j]; if(!twoSumMap[twoSum]){ twoSumArr.push(twoSum); twoSumMap[twoSum] = [[nums[i], nums[j]]]; }else if(!arrContains(twoSumMap[twoSum], nums[i], nums[j])){ twoSumMap[twoSum].push([nums[i], nums[j]]); } } } twoSumArr = twoSumArr.sort(sorting); var numA, numB, sum4; for(i = 0, j = twoSumArr.length - 1; i <= j;){ numA = twoSumMap[twoSumArr[i]], numB = twoSumMap[twoSumArr[j]]; sum4 = twoSumArr[i] + twoSumArr[j]; if(sum4 === target){ addCandidate(numA, numB, result); } if(sum4 < target){ i++; }else{ j--; } } return result; function verifyResult(arr){ var previous = null, count = 0; for(var i = 0; i < arr.length; i++){ if(arr[i] !== previous){ previous = arr[i]; count = 1; }else{ count++; if(count > countAppear[previous]){ return false; } } } return true; } function addCandidate(numA, numB, result){ var i, j, tmp; for(i = 0; i < numA.length; i++){ for(j = 0; j < numB.length; j++){ if(numA[i][1] <= numB[j][0]){ tmp = [numA[i][0], numA[i][1], numB[j][0], numB[j][1]]; if(verifyResult(tmp)){ result.push(tmp); } } } } } function arrContains(arr, small, large){ for(var i = 0; i < arr.length; i++){ if(arr[i][0] === small && arr[i][1] === large){ return true; } } return false; } function sorting(a, b){ if(a > b){ return 1; }else if(a < b){ return -1; }else{ return 0; } } };
相关文章推荐
- JS页面跳转使地址后面不显示参数
- JavaScript检测字符串中是否含有html标签实现方法
- JavaScript数组去重的3种方法和代码实例
- javascript常用的方法分享
- JavaScript框架是什么?怎样才能叫做框架?
- Backbone.js的一些使用技巧
- JavaScript的RequireJS库入门指南
- 使用RequireJS优化JavaScript引用代码的方法
- 在JavaScript应用中使用RequireJS来实现延迟加载
- JavaScript判断数组是否包含指定元素的方法
- JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
- JavaScript获得指定对象大小的方法
- JavaScript每天定时更换皮肤样式的方法
- JS随机调用指定函数的方法
- JS访问SWF的函数用法实例
- JS实现统计复选框选中个数并提示确定与取消的方法
- JS选中checkbox后获取table内一行TD所有数据的方法
- 为什么 JavaScript 会在移动端中胜出?
- js实现的各种排序算法
- js访问xml之节点操作