原题
Given an array with n objects colored red, white or blue, sort them in-place 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.
Example:
Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
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 a one-pass algorithm using only constant space?
Reference Answer
思路分析
这道题本身不难,难点在要求一次遍历完成排序。
这道题不允许使用排序库函数。那么最直观的解法是:遍历两遍数组,第一遍对0,1,2计数,第二遍对数组进行赋值,这样是可以ac的。但题目的要求是只使用常数空间,而且只能遍历一遍。那么思路就比较巧妙了。设置两个头尾指针,头指针p0指向的位置是0该放置的位置,尾指针p2指向的位置是2该放置的位置。i用来遍历整个数组,碰到0把它和p0指向的数交换,碰到2把它和p2指向的数交换,碰到1继续向后遍历。有点类似快速排序的分割数组这一步。
class Solution:
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
# if not nums:
# return []
# temp_list = [1 for i in range(len(nums))]
# min_index = 0
# max_index = len(nums) - 1
# for x in nums:
# if x == 0:
# temp_list[min_index] = 0
# min_index += 1
# if x == 2:
# temp_list[max_index] = 2
# max_index -= 1
# for index in range(len(nums)):
# nums[index] = temp_list[index]
if not nums:
return []
start_index = 0
end_index = len(nums) - 1
index = 0
while index <= end_index:
if nums[index] == 2:
nums[end_index], nums[index] = nums[index], nums[end_index]
end_index -= 1
elif nums[index] == 0:
nums[start_index], nums[index] = nums[index], nums[start_index]
start_index += 1
index += 1
else:
index += 1
Note:
- 本题在所含元素已知的前提下,完成一次遍历排序的思想很值得借鉴,即设置头指针p1,尾指针p2,i用来遍历整个数组,碰到0把它和p1指向的数交换,碰到2把它和p2指向的数交换,碰到1继续向后遍历。有点类似快速排序的分割数组这一步。