leetcode新年病房暴乱康复计划 15. 三数之和 16. 最接近的三数之和 18. 四数之和 JS解法
//15
var threeSum = function(nums) { var ans = []; var nums = nums.sort(function(a,b){return a - b}); var flag = 0; while(flag < nums.length - 2){ if (nums[flag] > 0){ break; } var l = flag + 1,r= nums.length - 1; while(l < r){ var res = nums[flag] + nums[l] + nums[r]; if(res === 0){ ans.push(new Array(nums[flag], nums[l], nums[r])); while(++l < r && nums[l - 1] === nums[l]){} while(l < --r && nums[r + 1] === nums[r]){} }else if(res < 0){ while(++l < r && nums[l - 1] === nums[l]){} }else{ while(l < --r && nums[r + 1] === nums[r]){} } } while(++flag < nums.length - 2 && nums[flag] === nums[flag - 1]){} } return ans; };
从第一个开始指定一个标尺,然后设置L=标尺+1,R=END双指针法贪心往内部推进 15题的关键是排序后最左侧为正数的优化 节约大量运行时间
//16 /** * @param {number[]} nums * @param {number} target * @return {number} */ var threeSumClosest = function(nums, target) { var ans = -99999999; var len = nums.length; nums.sort((a, b) => {return a - b;}); for(var i = 0; i < len - 2; i++){ var l = i + 1, r = len - 1; while(l < r){ var sum = nums[i] + nums[l] + nums[r]; if(Math.abs(ans - target) > Math.abs(sum - target)){ ans = sum; } sum = sum - target; if(sum < 0){ while(l < r && nums[l] === nums[++l]){} }else if(sum > 0){ while(l < r && nums[r] === nums[--r]){} }else{ break; } } if(ans === target) break; } return ans; };
16题就老老实实比吧 因为要凑数所以不能采取上题的优化
//18 /** * @param {number[]} nums * @param {number} target * @return {number[][]} */ var fourSum = function(nums, target) { var ans = []; var len = nums.length; nums.sort((a,b) => {return a - b}); for(var i = 0; i < len - 3; i++){ if(i > 0 && nums[i - 1] === nums[i]) continue; for(var j = i + 1; j < len - 2; j++){ if(j > i + 1 && nums[j - 1] === nums[j]) continue; var l = j + 1, r = len - 1; while(l < r){ var sum = nums[i] + nums[j] + nums[l] + nums[r]; if(sum < target){ while(l < r && nums[l] === nums[++l]){} }else if(sum > target){ while(l < r && nums[r] === nums[--r]){} }else{ ans.push([nums[i], nums[j], nums[l], nums[r]]); while(l < r && nums[l] === nums[++l]){} while(l < r && nums[r] === nums[--r]){} } } } } return ans; };
18这题相当于给16套了个壳 指定第一个为原来三数之和的标尺后 再把后面的按三数之和走一遍

浙公网安备 33010602011771号