给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
思路一
排序,首先想到的就是排序,排成一个有序序列
使用快排,时间复杂度O(nlogn);
void sortColors(int* nums, int numsSize){
quickSort(nums,0,numsSize-1);
}
void quickSort(int *number, int first, int last) {
int i, j, pivot;
int temp;
if (first<last) {
pivot = first;
i = first;
j = last;
while (i<j) {
while (number[i] <= number[pivot] && i<last)
i++;
while (number[j]>number[pivot])
j--;
if (i<j) {
temp = number[i];
number[i] = number[j];
number[j] = temp;
}
}
temp = number[pivot];
number[pivot] = number[j];
number[j] = temp;
quickSort(number, first, j - 1);
quickSort(number, j + 1, last);
}
}
思路二
双指针
两个指针p0,p1,一遍扫描,扫描到0就和p0交换位置,同时p0,p1后移,扫描到1就p1交换位置。但是如果扫到0的时候,p0<p1,这样就把本来的p1位置的1换到后面了,所以这时候就再换一次,p1换回来;
void swap(int *a,int *b){
int t=*a;
*a=*b;
*b=t;
}
void sortColors(int* nums, int numsSize){
int p0=0,p1=0;
for(int i=0;i<numsSize;i++){
if(nums[i]==0){
swap(&nums[i],&nums[p0]);
if(p0<p1){
swap(&nums[i],&nums[p1]);
}
p0++;
p1++;
}else if(nums[i]==1){
swap(&nums[i],&nums[p1]);
p1++;
}else{
}
}
}
思路三
双指针,也用p0,p1但是p1用来放2,当扫描次数i>=p1,就退出循环,减少了循环次数。思路和二一样,但是p1和i都是2的时候,交换后就会出现i走了,但是2没换,所以就要一直判断一直换;
void swap(int *a,int *b){
int t=*a;
*a=*b;
*b=t;
}
void sortColors(int* nums, int numsSize){
int p0=0,p1=numsSize-1;
for(int i=0;i<numsSize;i++){
while(nums[i]==2&&i<=p1){
swap(&nums[i],&nums[p1]);
p1--;
}
if(nums[i]==0){
swap(&nums[i],&nums[p0]);
p0++;
}
}
}