返回

快慢指针算法:LeetCode 26 题入门,80 题进阶

前端

快慢指针算法:巧妙解决数组难题

在编程的世界里,算法是解决问题的基石。其中,快慢指针算法作为一种巧妙高效的数组处理技术,在众多场景下大放异彩。本文将以 LeetCode 上的 26 和 80 两道题目为载体,带领你领略快慢指针算法的魅力。

什么是快慢指针算法?

快慢指针算法是一种遍历数组的技巧,它使用两个指针:

  • 快指针 :以比另一个指针更快的速度遍历数组。
  • 慢指针 :负责标记数组中不重复的元素。

通过巧妙地利用快慢指针的不同速度,我们可以高效地完成各种数组操作。

快慢指针算法在 LeetCode 26 题中的应用

题目:删除有序数组中的重复项

给定一个排序数组,请删除其中所有重复元素,并返回删除后数组的新长度。

快慢指针解法:

  1. 初始化快慢指针都指向数组开头。
  2. 快指针快速向右移动,跳过重复元素。
  3. 当快指针遇到与慢指针指向的元素不同的元素时,将该元素复制到慢指针指向的位置,并让慢指针右移一位。
  4. 重复步骤 2 和 3,直到快指针到达数组末尾。
  5. 返回慢指针的位置(此时指向最后一个不重复的元素)。

代码实现:

def removeDuplicates(nums):
    slow = 0  # 慢指针
    for fast in range(1, len(nums)):  # 快指针
        if nums[fast] != nums[slow]:
            slow += 1
            nums[slow] = nums[fast]
    return slow + 1

快慢指针算法在 LeetCode 80 题中的应用

题目:删除有序数组中的重复项 II

给定一个排序数组,删除所有重复元素,每个元素最多保留两个。

快慢指针解法:

在 LeetCode 26 题的基础上稍作修改,要求每个元素最多保留两个。我们可以使用一个变量 count 来记录当前元素重复出现的次数。

  1. 初始化快慢指针都指向数组开头。
  2. 快指针快速向右移动,跳过重复元素。
  3. 当快指针遇到与慢指针指向的元素不同的元素时,将该元素复制到慢指针指向的位置,并重置 count 为 1。
  4. 当快指针遇到与慢指针指向的元素相同的元素时,将 count 加 1。如果 count 小于或等于 2,则将该元素复制到慢指针指向的下一个位置,并让慢指针右移一位。
  5. 重复步骤 2、3、4,直到快指针到达数组末尾。
  6. 返回慢指针的位置(此时指向最后一个不重复或重复次数不超过 2 的元素)。

代码实现:

def removeDuplicatesII(nums):
    slow = 0  # 慢指针
    count = 1  # 元素重复次数
    for fast in range(1, len(nums)):  # 快指针
        if nums[fast] == nums[slow]:
            count += 1
            if count <= 2:
                slow += 1
                nums[slow] = nums[fast]
        else:
            count = 1
            slow += 1
            nums[slow] = nums[fast]
    return slow + 1

总结

快慢指针算法是一种简单有效的数组处理技巧,在 LeetCode 等编程竞赛平台上经常出现。通过巧妙地利用快慢指针的不同速度,我们可以高效地完成各种数组操作。

本文通过 LeetCode 26 和 80 两道经典题目,详细介绍了快慢指针算法的原理和应用。希望读者通过本文的学习,能够深入理解该算法,并在自己的编程实践中灵活运用。

常见问题解答

  1. 快慢指针算法的时间复杂度是多少?
    答案:时间复杂度为 O(n),其中 n 是数组的长度。

  2. 快慢指针算法的空间复杂度是多少?
    答案:空间复杂度为 O(1),因为我们只使用两个指针变量。

  3. 快慢指针算法有哪些优点?
    答案:优点包括效率高、空间占用少、易于理解和实现。

  4. 快慢指针算法有哪些缺点?
    答案:缺点是无法处理无序数组,且对于重复元素较多的数组效率较低。

  5. 在哪些场景中可以使用快慢指针算法?
    答案:快慢指针算法可用于查找数组中第一个不重复元素、删除重复元素、合并两个有序数组、找出数组中指定元素的起始和结束位置等场景。