显然对数组进行一次遍历记录0,1,2的个数,后再次从首至尾重写数组,可以在两次遍历完成任务。
更好的解决办法是利用Leetcode26.Remove_Duplicates_From_Sorted_Aarray的思路,前后各设置一个标志点,然后遍历数组,遇到0则向前边的标记点交换,标记点后移;遇到2则向后边的标记点交换,标记点前移。注意交换完需要检查一下交换过来的数是不是0或2,若是则需要再次交换。
时间复杂度:O(N)
C++代码:
class Solution {
public:
void sortColors(vector<int>& nums) {
if (nums.size() < 2)
return;
int pos_0 = 0, pos_2 = nums.size() - 1;
for (int i = pos_0; i < pos_2 + 1; i++)
{
while (nums[pos_0] == 0) { pos_0++; }
while (nums[pos_2] == 2) { pos_2--; }
if (i < pos_0)
i = pos_0;
if (i >= pos_2 + 1)
break;
if (nums[i] == 0)
swap(nums[pos_0++], nums[i]);
if (nums[i] == 2)
{
swap(nums[pos_2--], nums[i]);
if (nums[i] == 0)
i--;
}
}
}
};
三个标记(分别标记0,1,2)的更简洁版本:
class Solution {
public:
void sortColors(vector<int>& nums) {
int pos_0 = -1, pos_1 = -1, pos_2 = -1;
for (int x:nums) {
if (x == 0) {
nums[++pos_2] = 2;
nums[++pos_1] = 1;
nums[++pos_0] = 0;
}
else if (x == 1) {
nums[++pos_2] = 2;
nums[++pos_1] = 1;
}
else {
nums[++pos_2] = 2;
}
}
}
};