1. /**
    2. * @param {number[]} nums
    3. * @return {number[][]}
    4. */
    5. var threeSum = function(nums) {
    6. let ans = [];
    7. const len = nums.length;
    8. if(nums == null || len < 3) return ans;//数组的长度大于3
    9. nums.sort((a, b) => a - b); // 排序
    10. for (let i = 0; i < len ; i++) {
    11. if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
    12. if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
    13. let L = i+1;
    14. let R = len-1;
    15. while(L < R){//虽然里面还有两个循环,但是整体的L和R移动的时间内复杂度还是o(n)
    16. const sum = nums[i] + nums[L] + nums[R];
    17. if(sum == 0){
    18. ans.push([nums[i],nums[L],nums[R]]);
    19. while (L<R && nums[L] == nums[L+1]) L++; // 去重
    20. while (L<R && nums[R] == nums[R-1]) R--; // 去重
    21. L++;
    22. R--;
    23. }
    24. else if (sum < 0) L++;
    25. else if (sum > 0) R--;
    26. }
    27. }
    28. return ans;
    29. };
    1. /**
    2. * @param {number[]} nums
    3. * @return {number[][]}
    4. */
    5. var threeSum = function (nums) {
    6. // 找到 a b c
    7. // 排序应用场景:无序的数组里 查找目标和大小相关 查看是否可以利用排序 降低复杂度
    8. // 排序 n*logn
    9. let list = []
    10. if(nums.length < 3) {
    11. return []
    12. }
    13. // 最小 + 最大之和, 如果比目标值大,说明要缩小这个值,最大值左移,否则,最小值右移
    14. // [ 2, 3, 4, -5, 6, 7, 8]
    15. // 1
    16. nums.sort((a, b) => a - b) // n*lgn
    17. for(let i = 0; i < nums.length; i++) {
    18. if(nums[i] === nums[i-1]) {
    19. continue
    20. }
    21. // num[i] 为基准,找另外两个数组,数组之和, -num[i]
    22. let left = i + 1
    23. let right = nums.length - 1
    24. while (left < right) {
    25. if(right === i ) {
    26. right--
    27. } else if(nums[left] + nums[right] + nums[i] === 0) {
    28. // 命中
    29. list.push([nums[left], nums[right], nums[i]])
    30. // 继续找
    31. while(nums[left] === nums[left + 1]) {
    32. // 由于排序了,相同的数组在一起
    33. left++
    34. }
    35. left++
    36. while(nums[right] === nums[right-1]) {
    37. right--
    38. }
    39. right--
    40. } else if(nums[left] + nums[right] + nums[i] > 0) {
    41. // 数字太大了,需要小一些判断
    42. right--
    43. } else {
    44. // 数字太小了,需要大一些
    45. left++
    46. }
    47. }
    48. }
    49. return list
    50. }