首页 > 代码库 > LeetCode: Sort Colors 题解
LeetCode: 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.
click to show follow up.
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?
1 void sortColors(int A[], int n) { 2 int s0,s1,s2,i; 3 s0=s1=s2=0; 4 for(i=0;i<n;i++) 5 { 6 if(A[i]==0) s0++; 7 else if(A[i]==1) s1++; 8 else s2++; 9 } 10 for(i=0;i<s0;i++) A[i]=0; 11 for(i=s0;i<s0+s1;i++) A[i]=1; 12 for(;i<n;i++) A[i]=2; 13 }
然而,正如Follow up中所表述的一样,计数排序需要两次遍历数组,那么我们能否找到一种只需要遍历一次数组,就能将其排序的方法呢?
答案是有的:
由于只有三种颜色,那么红色必然在数组的左边,而蓝色必然在数组的右边。
那么我们只需要两个变量记录红色所在区域的边界[0, i], 以及蓝色所在区域的边界[j,n-1]。那么白色所在的区域必然为(i,j).
怎样得到红蓝两色的边界呢?
初始化: 红色边界i=0; 蓝色边界j=n-1;
为了加速运算,可以预处理,分别从左至右,从右至左,找到红蓝边界,缩小搜索范围。见代码line[3,4]
假设当前位置为k
(1) A[k] 为红色, 那么将该元素同红色右边界的后一个数互换。 A[k] ~ A[i++]
(2) A[k] 为蓝色, 那么将该元素同蓝色左边界的前一个数互换。 A[k] ~ A[j--]
(3) A[k] 为白色, 那么当前无需交换, k=k+1;
终止条件 k>j 此时不可能出现白色,可以退出了。
该过程时间复杂度 O(n).
1 void sortColors(int A[], int n) { 2 int i=0,j=n-1,k; 3 while(A[i]==0) i++; 4 while(A[j]==2) j--; 5 6 k=i; 7 while(k<=j) 8 { 9 if(A[k]==0) 10 { 11 if(A[i]==0) 12 k++; 13 else 14 swap(A[i],A[k]); 15 i++; 16 } 17 else if(A[k]==2) 18 { 19 swap(A[j],A[k]); 20 --j; 21 } 22 else 23 k++; 24 } 25 }
转载请注明出处:http://www.cnblogs.com/double-win/ 谢谢