LeetCode Day3 27 移除元素 26 删除有序数组中的重复项 75颜色分类

2 阅读2分钟

27 移除元素

独立完成

核心思路:快指针负责遍历整个列表,寻找所有不等于 val 的元素;慢指针指向下一个有效元素应该写入的位置。每找到一个有效元素,就把它写到慢指针位置,然后慢指针向后移动一位。最终慢指针的值就是有效元素的数量。

    def removeElement(self, nums: List[int], val: int) -> int:
        slow = 0

        for fast in range(len(nums)):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1

        return slow

时间复杂度:O(n)

空间复杂度:O(1)

26 删除有序数组

独立完成

核心思路:利用快慢指针。慢指针始终指向当前最后一个不重复元素的位置,快指针从前往后遍历数组。当 nums[fast] != nums[slow] 时,说明找到了一个新的不重复元素,于是先将慢指针向后移动一位,再把这个新元素写入 nums[slow]。由于 slow 记录的是最后一个有效元素的索引,并且索引从 0 开始,所以最终不同元素的数量是 slow + 1,前提是数组不为空,因为空数组没有第一个元素,此时不能直接返回 slow + 1

    def removeDuplicates(self, nums: List[int]) -> int:
        if not nums:
            return 0
        slow = 0
        for fast in range(len(nums)):
            if nums[fast] != nums[slow]:
                slow += 1
                nums[slow] = nums[fast]
        return 1+slow

时间复杂度:O(n)

空间复杂度:O(1)

75颜色分类

半独立完成

核心思路:因为数组中只可能有 0、1、2,可以先统计每个数字出现多少次,再重新写回数组

    def sortColors(self, nums: List[int]) -> None:
        count_0 = 0
        count_1 = 0
        count_2 = 0

        for num in nums:
            if num == 0:
                count_0 += 1
            elif num == 1:
                count_1 += 1
            else:
                count_2 += 1

        index = 0

        for _ in range(count_0):
            nums[index] = 0
            index += 1

        for _ in range(count_1):
            nums[index] = 1
            index += 1

        for _ in range(count_2):
            nums[index] = 2
            index += 1

时间复杂度:O(n)

空间复杂度:O(1)

优化思路:使用三指针,将数组分成已排好 0 的区域、已排好 1 的区域、未处理区域和已排好 2 的区域。current 遍历未处理区域,遇到 0 就交换到左侧,遇到 1 就继续前进,遇到 2 就交换到右侧。处理 2 后不能移动 current,因为从右侧换过来的元素还没有检查。

    def sortColors(self, nums: list[int]) -> None:
        left = 0
        current = 0
        right = len(nums) - 1

        while current <= right:
            if nums[current] == 0:
                nums[left], nums[current] = nums[current], nums[left]
                left += 1
                current += 1

            elif nums[current] == 1:
                current += 1

            else:
                nums[current], nums[right] = nums[right], nums[current]
                right -= 1