/** * @param {number[]} nums * @return {number[][]} */var threeSum = function(nums) {let ans = []; const len = nums.length; if(nums == null || len < 3) return ans;//数组的长度大于3 nums.sort((a, b) => a - b); // 排序 for (let i = 0; i < len ; i++) { if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环 if(i > 0 && nums[i] == nums[i-1]) continue; // 去重 let L = i+1; let R = len-1; while(L < R){//虽然里面还有两个循环,但是整体的L和R移动的时间内复杂度还是o(n) const sum = nums[i] + nums[L] + nums[R]; if(sum == 0){ ans.push([nums[i],nums[L],nums[R]]); while (L<R && nums[L] == nums[L+1]) L++; // 去重 while (L<R && nums[R] == nums[R-1]) R--; // 去重 L++; R--; } else if (sum < 0) L++; else if (sum > 0) R--; } } return ans;};
/** * @param {number[]} nums * @return {number[][]} */var threeSum = function (nums) { // 找到 a b c // 排序应用场景:无序的数组里 查找目标和大小相关 查看是否可以利用排序 降低复杂度 // 排序 n*logn let list = [] if(nums.length < 3) { return [] } // 最小 + 最大之和, 如果比目标值大,说明要缩小这个值,最大值左移,否则,最小值右移 // [ 2, 3, 4, -5, 6, 7, 8] // 1 nums.sort((a, b) => a - b) // n*lgn for(let i = 0; i < nums.length; i++) { if(nums[i] === nums[i-1]) { continue } // num[i] 为基准,找另外两个数组,数组之和, -num[i] let left = i + 1 let right = nums.length - 1 while (left < right) { if(right === i ) { right-- } else if(nums[left] + nums[right] + nums[i] === 0) { // 命中 list.push([nums[left], nums[right], nums[i]]) // 继续找 while(nums[left] === nums[left + 1]) { // 由于排序了,相同的数组在一起 left++ } left++ while(nums[right] === nums[right-1]) { right-- } right-- } else if(nums[left] + nums[right] + nums[i] > 0) { // 数字太大了,需要小一些判断 right-- } else { // 数字太小了,需要大一些 left++ } } } return list}