题目描述如下:
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0] 输出: [0,0,1,1,2,2]
这道题有很多种做法,一种是直接对原来的vector数组进行排序(如冒泡排序),另一种是官方给的做法,即先通过迭代计算出元素0、1、2的个数,然后重写当前数组,这两种方法,都属于暴力方法,需要两次循环,时间复杂度分别为O(n^2)和O(2*n),效率比较低,进阶的做法通过一遍循环即可解决该问题,这种方法是三指针法。
下面先给出两种暴力法的代码:
1、直接排序:
C++:
class Solution {
public:
void sortColors(vector<int>& nums) {
int i,j,temp;
for(i=0;i<nums.size();i++){
for(j=i;j<nums.size();j++){
if(nums[j]<=nums[i]){
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
}
};
2、先通过迭代计算出元素0、1、2的个数,然后重写当前数组
C++:
class Solution {
public:
void sortColors(vector<int>& nums) {
int figure1=0,figure2=0,figure3=0;
int length = nums.size(),i;
for(i=0;i<length;i++){//计算出0、1、2元素的个数
if(nums[i]==0){figure1++;}
else if(nums[i]==1){figure2++;}
else if(nums[i]==2){figure3++;}
}
for(i=0;i<length;i++){//重写数组
if(figure1!=0){nums[i]=0;figure1--;continue;}
else if(figure2!=0){nums[i]=1;figure2--;continue;}
else if(figure3!=0){nums[i]=2;figure3--;continue;}
}
}
};
python:
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
#计算元素0、1、2的个数
figure1 = nums.count(0)
figure2 = nums.count(1)
figure3 = nums.count(2)
#重写数组
for i in range(len(nums)):
if figure1!=0:
nums[i] = 0
figure1 -= 1
elif figure2!=0:
nums[i] = 1
figure2 -= 1
elif figure3!=0:
nums[i] = 2
figure3 -= 1
进阶做法(三指针法):
思路如下:
-
初始化0的最右边界:
p0 = 0
。在整个算法执行过程中nums[idx < p0] = 0
. -
初始化2的最左边界 :
p2 = n - 1
。在整个算法执行过程中nums[idx > p2] = 2
. -
初始化当前考虑的元素序号 :i
= 0
. -
While
curr <= p2
:-
若
nums[i] = 0
:交换第i
个 和 第p0
个 元素,并将指针都向右移。 -
若
nums[i] = 2
:交换第i
个和第p2
个元素,并将p2
指针左移 。 -
若
nums[i] = 1
:将指针i
右移。
-
C++代码如下:
class Solution {
public:
void sortColors(vector<int>& nums) {
#三个指针分别为p0、p2、i
int p0=0,p2=nums.size()-1;
int i=0;
while(i<=p2){
if(nums[i]==0){
nums[i] = nums[p0];
nums[p0] = 0;
p0++;
i++;
}
else if(nums[i]==2){
nums[i] = nums[p2];
nums[p2] = 2;
p2--;
}
else{i++;}
}
}
};