返回

大揭秘!LeetCode从两数之和到四数之和的进化史(JS实现)

前端

算法的进化:从两数之和到四数之和

前言

算法是解决问题的步骤和策略,在计算机编程中扮演着至关重要的角色。LeetCode 是一个流行的算法竞赛平台,汇聚了全球各地的程序员,共同探索算法的奥秘。从两数之和四数之和 ,这些算法题的进化史揭示了算法和编程的奥秘。本文将带您领略JavaScriptJS )实现的精髓,并分享优化算法以提高效率的秘诀。

两数之和:暴力破解与哈希表优化

两数之和LeetCode 中最经典的算法题之一。给定一个整数数组和一个目标和,要求找出数组中两个数的和等于目标和。

暴力破解 方法最简单,但执行效率低。它逐一对数组中的所有元素进行遍历,并计算它们的和。这种方法的时间复杂度为O(n²) ,其中n 是数组的长度。

为了提高效率,我们可以使用哈希表 优化算法。哈希表是一种数据结构,它允许我们快速查找和插入元素。我们将数组中的每个元素及其索引存储在哈希表中。这样,当我们遍历数组时,我们可以通过查询哈希表来查找是否有另一个元素与之相加等于目标和。这种方法的时间复杂度为O(n) ,大大降低了算法的复杂度。

// 哈希表实现的两数之和算法

function twoSum(nums, target) {
  const hashtable = {};

  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];

    if (hashtable[complement] !== undefined) {
      return [hashtable[complement], i];
    }

    hashtable[nums[i]] = i;
  }

  return null;
}

三数之和:暴力破解与双指针优化

三数之和两数之和 的延伸,它要求找出数组中三个数的和等于目标和。

暴力破解 方法与两数之和 类似,时间复杂度为**O(n³) ** 。

为了提高效率,我们可以使用双指针 优化算法。双指针算法从数组的两端向中间移动,并计算指针指向的三个元素的和。如果和等于目标和,则返回这三个元素。如果和小于目标和,则将左指针向右移动。如果和大于目标和,则将右指针向左移动。这种方法的时间复杂度为O(n²) ,大大降低了算法的复杂度。

// 双指针实现的三数之和算法

function threeSum(nums, target) {
  nums.sort((a, b) => a - b);

  const result = [];

  for (let i = 0; i < nums.length - 2; i++) {
    let left = i + 1;
    let right = nums.length - 1;

    while (left < right) {
      const sum = nums[i] + nums[left] + nums[right];

      if (sum === target) {
        result.push([nums[i], nums[left], nums[right]]);

        while (nums[left] === nums[left + 1]) left++;
        while (nums[right] === nums[right - 1]) right--;

        left++;
        right--;
      } else if (sum < target) {
        left++;
      } else {
        right--;
      }
    }
  }

  return result;
}

四数之和:暴力破解与双指针优化

四数之和三数之和 的延伸,它要求找出数组中四个数的和等于目标和。

暴力破解 方法与三数之和 类似,时间复杂度为O(n⁴)

为了提高效率,我们可以使用双指针 优化算法。双指针算法与三数之和 类似,但增加了额外的内层循环,从数组的两端向中间移动,并计算指针指向的四个元素的和。这种方法的时间复杂度为**O(n³) ** ,大大降低了算法的复杂度。

// 双指针实现的四数之和算法

function fourSum(nums, target) {
  nums.sort((a, b) => a - b);

  const result = [];

  for (let i = 0; i < nums.length - 3; i++) {
    if (i > 0 && nums[i] === nums[i - 1]) continue;

    for (let j = i + 1; j < nums.length - 2; j++) {
      if (j > i + 1 && nums[j] === nums[j - 1]) continue;

      let left = j + 1;
      let right = nums.length - 1;

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

        if (sum === target) {
          result.push([nums[i], nums[j], nums[left], nums[right]]);

          while (nums[left] === nums[left + 1]) left++;
          while (nums[right] === nums[right - 1]) right--;

          left++;
          right--;
        } else if (sum < target) {
          left++;
        } else {
          right--;
        }
      }
    }
  }

  return result;
}

结论

LeetCode 算法题的进化史揭示了算法和编程的奥秘。通过优化算法,我们可以大大提高效率。本文中的JS 实现和优化技巧将帮助您提升编程能力,更有效地解决算法问题。

常见问题解答

  1. 如何判断一个算法的效率?

    算法的效率通常使用时间复杂度空间复杂度 来衡量。

  2. 哈希表是如何工作的?

    哈希表将键映射到值,并允许快速查询和插入。

  3. 双指针算法有什么优势?

    双指针算法避免了三重和四重循环,从而降低了算法的复杂度。

  4. 优化算法时应考虑哪些因素?

    优化算法时,应考虑算法的时间复杂度、空间复杂度以及代码的可读性和可维护性。

  5. 如何进一步提高算法的效率?

    可以使用动态规划、记忆化和剪枝等技术进一步提高算法的效率。