代码改变世界

[LeetCode 75] Sort Colors

2017-11-20 00:16  naturesound  阅读(151)  评论(0编辑  收藏  举报

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?

-------------------------------------------------

基本思想是扩展Two Pointer的思路,增加一个pointer,变成Three Pointer(left, mid, right)。关键是以中间的mid指针为轴心,让其不断和两边的left和right比较并交换。

这里提供三种解法,都很简短:

第一种解法是我自己的,比较straight foward:

1)将mid指针定位到非1的位置,将right指针定位到非2的位置;

2)然后判断:若nums[mid]为0,则将nums[mid]和nums[left]交换,并且left和mid各自增1;

                      否则nums[mid]一定为2,将其与nums[right]交换,这里要注意的是由于nums[right]的值也可能为0,所以这里交换之后只有right自减1,mid保持不变,以供继续考察。

3)还有一个注意点:循环条件是mid <=right,等号不能少,因为当right == mid时只能判断出num[mid]是非2的数,不能判断其是0还是1。

 

第二种解法,第三种解法都是以mid为轴:

如果mid为0,则与left交换,并均自增1;如果mid为2,则与right交换,right自减1;如果mid为1, mid自增1。

这三种解法都是一次遍历的O(n)时间复杂度,但第一种解法更高效,因为没有冗余的交换操作,第三种解法虽然实现简单,

 1 void sortColors(vector<int>& nums) {
 2         if(nums.empty()) return;
 3         int p0 = 0, p1 = 0, p2 = nums.size()-1;
 4         while(p1 <= p2){
 5             while(p1 < p2 && nums[p1] == 1) p1++;
 6             while(p1 < p2 && nums[p2] == 2) p2--;
 7             if(nums[p1] == 0) swap(nums[p0++], nums[p1++]);
 8             else swap(nums[p1], nums[p2--]);
 9         }
10     }
1. 内嵌While解法
 1     void sortColors(vector<int>& nums) {
 2         int left = 0, mid = 0, right = nums.size()-1;
 3         while(mid <= right){
 4             if(nums[mid] == 0){
 5                 swap(nums[left++], nums[mid++]);
 6             }else if(nums[mid] == 2){
 7                 swap(nums[mid], nums[right--]);
 8             }else mid++;
 9         }
10     }
2.以mid为轴心
1         void sortColors(int A[], int n) {
2             int second=n-1, zero=0;
3             for (int i=0; i<=second; i++) {
4                 while (A[i]==2 && i<second) swap(A[i], A[second--]);
5                 while (A[i]==0 && i>zero) swap(A[i], A[zero++]);
6             }
7         }
3.while + mid轴心