【LeetCode】Sort Colors

Posted on 2015-09-01 13:29  Maples7  阅读(412)  评论(0编辑  收藏  举报

Sort Colors

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note:
You are not suppose to use the library's sort function for this problem.

Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.

Could you come up with an one-pass algorithm using only constant space?

 


 

 

Solution:

 

扫描两趟算法:

  即 counting sort,第一趟给 0、1、2 分别计数,第二趟直接在相应位置上 overwrite value。

 

扫描一趟算法:

  由于整个array只有三个值,我们实际上需要做的工作便是把所有的 0 移到 array 头部位置,把所有的 2 移到 array 尾部位置,剩下的 1 便自然被挪到了中间位置。

  考虑两个指针,一个head指示“0头部”即将要“占领”到的位置,初始值为0,递增;另一个tail指示“2尾部”即将要“占领”到的位置,初始值为 len(nums)-1,递减。

  从左至右扫描,当扫描到当前位置 i 时,如果值为 0 并且不在“0头部”( i >= head )时,此时需要把 i 与 head 进行值交换,“0头部”长度自然拓展1,而 i 位置上的值变得不确定,此时保持 i 的值不变;如果值为 1 并且不在“2尾部”( i <= tail )时,此时需要把 i 与 tail 进行值交换,“2尾部”长度自然拓展1,而 i 位置上的值变得不确定,此时保持 i 的值不变;其他情况(在“0头部”或“2尾部”,或者当前位置值为1)则直接把扫描指针 i 加 1 即可。

  最后,本来扫描可以一直进行到 len(nums)-1,而由于扫描时已经可以确定“2尾部”中的2全部都已经在合适的位置上,所以扫描到 tail 即可终止循环( i <= tail )。

 

  代码如下:

  

 1 class Solution(object):
 2     def sortColors(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: void Do not return anything, modify nums in-place instead.
 6         """
 7         i, head, tail =0, 0, len(nums)-1
 8         while i <= tail:
 9             if nums[i] == 0 and i >= head:
10                 nums[i], nums[head] = nums[head], nums[i]
11                 head += 1
12             elif nums[i] == 2 and i <= tail:
13                 nums[i], nums[tail] = nums[tail], nums[i]
14                 tail -= 1
15             else:
16                 i += 1