标签:array two pointers sort leetcode
题目: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?
Answer 1: 计数排序标准方法
思路:题目要求我们将数组排序,并且知道数组内元素只包含0,1,2. 非常适合用计数排序。计数排序是一种稳定的线性时间排序算法,需要额外使用一个空间数组C存储计数, 其中第i个元素是带排序数组A中值等于i的元素的个数让,然后根据数组C来将A中的元素排到正确的位置。
算法步骤:
class Solution { public: void sortColors(int A[], int n) { int C[3] = {0}; vector<int> B(n, 0); //统计每个数字num出现的次数,存入数组C[num]中 for(int i = 0; i < n; i++) { int num = A[i]; C[num]++; } //求计数和 for(int i = 1; i < 3; i++) { C[i] += C[i-1]; } //反向填充目标数组 for(int j = n-1; j >= 0; j--) { int num = A[j]; B[C[num]-1] = num; C[num]--; } //赋值回原数组 for(int i = 0; i < n; i++) { A[i] = B[i]; } return; } };
思路:我们对数组中的元素进行排序,数组元素只包含0,1,2。我们可以借鉴快速排序的划分的思想,选一个枢纽,我们选择1为枢纽元对数组进行划分,使得0在数组的左边,2在数组的右边,1在数组的中间。我们维护两个变量,zeroEnd表示放0那部分的尾部索引,碰到0,我们就将这个元素放到zeroEnd+1的地方,twoBegin表示放2的那部分的首部索引,如果碰到2,我们就将这个元素放到twoBegin-1处,碰到1,我们就将指针后移。
Attention:
1. &&语句,如果判断前面不成立,就不会执行后面的语句,所以如果不是1或者2,不会移动zeroEnd和twoBegin索引位置。
if(A[i] == 0 && i != ++zeroEnd) swap(A[zeroEnd], A[i]); else if(A[i] == 2 && i != --twoBegin) swap(A[twoBegin], A[i]);
2. 交换后,我们把1和2放到合适的位置,没有移动i, 继续判断A[i].
3. 当i和twoBegin相遇时,说明我们把所有数字都排好序了。如果写成 (i < n)作为迭代终止条件,会得到错误的结果,会把后面的2都置换到前面,打乱了排序。
while(i < twoBegin)复杂度:O(N) 只遍历了一遍数组,常数空间复杂度。
AC Code:
class Solution { public: void sortColors(int A[], int n) { int i = 0; int zeroEnd = -1; //设置两个索引初值 int twoBegin = n; while(i < twoBegin) { if(A[i] == 0 && i != ++zeroEnd) //zeroEnd维护了0的最后一个位置,zeroEnd+1是紧接着的下一个位置。 swap(A[i], A[zeroEnd]); else if(A[i] == 2 && i != --twoBegin) //twoBegin维护了2的最前面的一个位置,twoBegin-1是紧接着的前一个位置 swap(A[i], A[twoBegin]); else i++; } return; } };
[C++]LeetCode: 127 Sort Colors (计数排序 & 快速排序)
标签:array two pointers sort leetcode
原文地址:http://blog.csdn.net/cinderella_niu/article/details/43193583