返回

LeetCode每日一题 - 15. 三数之和:巧妙运用的排序与指针技巧

前端

在LeetCode每日一题系列中,我们继续探索数组相关问题。今天,我们聚焦于一个经典算法题——15. 三数之和。该题要求我们查找数组中三个元素的和为给定目标值的所有可能组合。

巧用排序与双指针

解决三数之和问题的关键在于运用排序与双指针技巧。首先,我们对输入数组进行排序,以便快速确定元素的相对位置。排序后,我们使用两个指针ij分别指向数组的第一个和最后一个元素。

指针移动规则

指针ij的移动规则如下:

  1. 如果nums[i] + nums[j] + nums[mid] < target,则i向右移动。
  2. 如果nums[i] + nums[j] + nums[mid] > target,则j向左移动。
  3. 如果nums[i] + nums[j] + nums[mid] == target,则找到一个符合条件的三元组。将i向右移动以查找下一个可能的组合,并重置j为数组的最后一个元素。

时间复杂度分析

三数之和算法的时间复杂度为O(n^2),其中n为数组的长度。这是因为我们对数组进行排序(O(nlogn)),然后使用双指针遍历数组(O(n^2))。

示例代码

以下是用JavaScript实现三数之和算法的示例代码:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
const threeSum = (nums, target) => {
  nums.sort((a, b) => a - b); // 排序数组
  const result = [];

  for (let i = 0; i < nums.length - 2; i++) {
    if (i > 0 && nums[i] === nums[i - 1]) continue; // 跳过重复的元素

    let j = i + 1;
    let k = nums.length - 1;

    while (j < k) {
      const sum = nums[i] + nums[j] + nums[k];

      if (sum < target) {
        j++;
      } else if (sum > target) {
        k--;
      } else {
        result.push([nums[i], nums[j], nums[k]]);

        while (j < k && nums[j] === nums[j + 1]) j++; // 跳过重复的元素
        while (j < k && nums[k] === nums[k - 1]) k--; // 跳过重复的元素
        j++;
        k--;
      }
    }
  }

  return result;
};

结语

三数之和算法是一道经典的数组相关问题,充分运用了排序与双指针技巧。通过理解其算法思想和实现细节,我们能够高效地解决此类问题,在实际开发中大显身手。

SEO优化