题目描述:给定一个包含红,白,蓝且长度为 n 的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。我们可以使用整数 0,1 和 2 分别代表红,白,蓝。
样例:给你数组 [1, 0, 1, 2], 需要将该数组原地排序为 [0, 1, 1, 2]。
想一想这个问题,其实就是对三个不同数字组成的数组排序。
因为就三个不同数字,所以自然而然想到桶排序(详见:点击打开链接),但是这里有点不同的是,和我们在链接中给出的例子相比,数组可重复。又要求是原地排序,所以不难想到之前在快速排序(详见:点击打开链接)中用到的那种方法,就是不断令符合某种要求的元素向一边靠拢(想想在快排里面,就是让小于枢轴的元素向左靠拢,同时交换操作使得大于枢轴的元素向右靠拢)。因为此处只有0, 1, 2三个数字,所以考虑设置三个指针:first, second, cur,他们的作用如下:
first: 始终指向排好的0所在的最后一个位置的后一个位置(比如说已经排好了2个0,位置肯定是0,1了,那么first指向2)
second: 靠拢在右边的2的第一个位置的前一个位置
cur: 用来遍历数组
也就是说,我的基本思路是这样的:遍历数组,将0靠拢在最左边,将2靠拢在最右边,靠拢的方法还是快排里面交换元素的方法(不会的看上边链接)最后,中间的自然全部都是1。排序完成。
可以直接上代码了:
class Solution:
"""
@param nums: A list of integer which is 0, 1 or 2
@return: nothing
"""
def sortColors(self, nums):
n = len(nums)
if n == 0:
return nums
# first指向靠拢好的0之后的一位
# second指向靠拢好的1之前的一位
# cur指向当前要处理的位置
first, cur, second = 0, 0, n - 1
# 当前要处理的位置最多和靠拢好的1之前的一位相同,否则,说明排序已经完成
while cur <= second:
if nums[cur] == 0:
nums[cur], nums[first] = nums[first], nums[cur]
first += 1
cur += 1
elif nums[cur] == 2:
nums[cur], nums[second] = nums[second], nums[cur]
second -= 1
else:
cur += 1
return nums
# write your code here
这道题其实是桶排序的思想加快速排序的技巧组合而成的。