Skip to content

LeetCode题解:15. 三数之和,JavaScript双循环+双指针,详细注释 #98

@chencl1986

Description

@chencl1986

原题链接:https://leetcode-cn.com/problems/3sum/

该题解为三数之和(排序+双指针,易懂图解)的JavaScript实现,并附上了详细注释,帮助理解。

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function (nums) {
  let result = [];
  nums.sort((a, b) => a - b);

  for (let k = 0; k < nums.length; k++) {
    // 当前值大于0时,3个数都大于0,3数之和必然大于0,无需判断
    if (nums[k] > 0) {
      break;
    }

    // // 如果当前值与前一个值相等,即为已经处理过
    if (nums[k] === nums[k - 1]) {
      continue;
    }

    // 使用i和j双指正来遍历k之后的元素,查找满足条件的值
    let i = k + 1;
    let j = nums.length - 1;

    // 双指针解法
    // i小于j表示指针还未查询完所有数组
    while (i < j) {
      let sum = nums[k] + nums[i] + nums[j];

      // sum小于0,表示nums[i]的值偏小,可以将i指针向后移动
      if (sum < 0) {
        i++;
        // 避免查找i指针对应的相同值
        while (i < j && nums[i] === nums[i - 1]) {
          i++;
        }
      }

      // sum大于0,表示nums[i]的值偏大,可以将j指针向前移动
      if (sum > 0) {
        j--;
        // 避免查找j指针对应的相同值
        while (i < j && nums[j] === nums[j + 1]) {
          j--;
        }
      }

      // sum等于0,表示已经找到了结果,此时将i和j向内移动
      // 由于可能有不止一个解,需要继续寻找
      if (sum === 0) {
        result.push([nums[k], nums[i], nums[j]]);
        i++;
        j--;
        // while循环必须在每个逻辑中单独处理
        // 如果在所有逻辑之后统一处理i、j,会造成部分结果被跳过
        // 避免查找i指针对应的相同值
        while (i < j && nums[i] === nums[i - 1]) {
          i++;
        }
        // 避免查找j指针对应的相同值
        while (i < j && nums[j] === nums[j + 1]) {
          j--;
        }
      }
    }
  }

  return result;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions