LeetCode【0075】颜色分类

1 中文题目

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

使用整数 012 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题

示例:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
输入:nums = [2,0,1]
输出:[0,1,2]

提示:

  • n = = n u m s . l e n g t h n == nums.length n==nums.length
  • 1 ≤ n ≤ 300 1 \leq n \leq 300 1n300
  • nums[i]012

2 求解方法:三指针

2.1 方法思路

方法核心

使用三指针对数组进行一次遍历,left指针左侧都是0right指针右侧都是2,中间区域都是1,通过不断交换元素并移动指针,最终完成数组的原地排序,这种方法只需要一次遍历就能完成排序,且不需要额外空间。

实现步骤

(1)初始化阶段

  • 设置三个指针:
    • left:指向0的右边界
    • right:指向2的左边界
    • curr:当前处理的位置
  • 所有指针初始位置设置

(2)遍历处理阶段

  • 处理当前元素(nums[curr]):
    • 如果是0:与left位置交换,left和curr都右移
    • 如果是2:与right位置交换,right左移,curr不动
    • 如果是1:curr右移
  • 维护区域特性:
    • [0, left):全是0
    • [left, curr):全是1
    • (right, n-1]:全是2
    • [curr, right]:待处理区域

(3)终止条件

  • 当curr超过right时停止
  • 此时数组已经完成分类排序

方法示例

nums = [2,0,2,1,1,0] 为例:

初始状态:
nums = [2,0,2,1,1,0]
left = 0, curr = 0, right = 5

第一步:nums[curr] = 2
交换nums[curr]和nums[right]
nums = [0,0,2,1,1,2]
right = 4

第二步:nums[curr] = 0
交换nums[curr]和nums[left]
nums = [0,0,2,1,1,2]
left = 1, curr = 1

第三步:nums[curr] = 0
交换nums[curr]和nums[left]
nums = [0,0,2,1,1,2]
left = 2, curr = 2

第四步:nums[curr] = 2
交换nums[curr]和nums[right]
nums = [0,0,1,1,2,2]
right = 3

第五步:nums[curr] = 1
curr右移
nums = [0,0,1,1,2,2]
curr = 3

第六步:nums[curr] = 1
curr右移
nums = [0,0,1,1,2,2]
curr = 4

结束:curr > right,排序完成

2.2 Python代码

class Solution:
    def sortColors(self, nums: list[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 使用三个指针进行排序
        # left指向0的右边界(下一个0应该放置的位置)
        # right指向2的左边界(下一个2应该放置的位置)
        # curr是当前处理的位置
        left = curr = 0
        right = len(nums) - 1
        
        # 当curr指针没有超过right指针时继续处理
        while curr <= right:
            if nums[curr] == 0:
                # 遇到0时,将其与left位置的数交换
                # left和curr都向右移动
                nums[left], nums[curr] = nums[curr], nums[left]
                left += 1
                curr += 1
            elif nums[curr] == 2:
                # 遇到2时,将其与right位置的数交换
                # right向左移动,curr不移动(因为交换来的数还需要处理)
                nums[right], nums[curr] = nums[curr], nums[right]
                right -= 1
            else:
                # 遇到1时,不需要交换,curr直接向右移动
                curr += 1

2.3 复杂度分析

  • 时间复杂度:O(n),n是数组的长度
    • 只需要一次遍历
    • 每个元素最多被交换一次
    • 所有操作都是常数时间
  • 空间复杂度:O(1)
    • 只使用了三个指针变量
    • 所有操作都是原地进行

3 题目总结

题目难度:中等
数据结构:数组
应用算法:三指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AnFany

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值