1 问题
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]
2 答案
自己写的,从头遍历,如果为0,则放到最前,如果为2,则放到最后,同时删除,思路没问题,但是由于题目要求只能原地修改,可能不能直接拼接数组,导致结果输出与调试时的对不上
两个指针的写法尝试过,不够用,要三个指针
class Solution:
def sortColors(self, nums: List[int]) -> None:
# 从头遍历,如果为0,则放到最前,如果为2,则放到最后,同时删除
i = 0
j = len(nums) - 1
while i < len(nums):
if nums[i] == 0:
nums.pop(i)
nums = [0] + nums
i+=1
while j > -1:
if nums[j] == 2:
nums.pop(j)
nums = nums + [2]
if nums[j] == 0:
break
j-=1
官方解,partition,实际上是利用三个指针
写代码的时候需要注意到设置的变量以及区间的定义,也就是 循环不变量。循环不变量 简单说就是在循环的过程中保持不变的性质,这个性质是人为根据需要解决的任务定义的。个人理解循环不变量在本题中就是每个区间的索引,以及开闭区间的情况。
class Solution:
def sortColors(self, nums: List[int]) -> None:
# all in [0, zero) = 0 # 循环不变量,都是索引
# all in [zero, i) = 1
# all in [two, len - 1] = 2
def swap(nums, index1, index2):
nums[index1], nums[index2] = nums[index2], nums[index1]
size = len(nums)
if size < 2:
return
zero = 0 # 刚开始区间内都不应该有值
two = size
i = 0
while i < two:
if nums[i] == 0: # 属于第一个区间
swap(nums, i, zero)
i += 1
zero += 1
elif nums[i] == 1: # 属于第二个区间
i += 1
else: # 属于第三个区间
two -= 1 # 需要先变换索引,还是交换数值要搞清楚
swap(nums, i, two)
https://leetcode.cn/problems/sort-colors/solutions/71322/kuai-su-pai-xu-partition-guo-cheng-she-ji-xun-huan/