这个题目来一个排序就可以解决,但是让我感兴趣的是如何遍历一边就弄完,先附上我写的代码:
class Solution {
public:
void sortColors(vector<int>& n) {
int point =0;//基本的单指针o(n),交换0和1,遍历两次;
for(int i=0;i<n.size();i++)
{
if(n[i]==0) swap(n[point],n[i]),point++;
}
for(int i=point;i<n.size();i++)
{
if(n[i]==1) swap(n[point],n[i]),point++;
}
}
};
先将所有的0全部置换到前面,然后再把所有的1置换到前面,这样就成功了,但是这还是便利了两次;
然后我翻阅了评论区,找到了大佬的解法:
class Solution {
public:
void sortColors(vector<int>& n) {
int num0 = 0, num1 = 0;
for(int i = 0; i < n.size(); i++) {
if(n[i] == 0) {
n[i] = 2;
n[num1++] = 1;
n[num0++] = 0;
}else if(n[i] == 1) {
n[i] = 2;
n[num1++] = 1;
}else {
n[i] = 2;
}
}
}
};
三个指针num0、num1、i将数组nums分成了3个分区,从左往右依次存储0、1、2。 三个指针分别指向各自分区的尾部。 从左到右遍历数组nums,(1)如果nums[i]=0,则1、2区都后移一个位置,给新来的0腾地方。 (2)如果是nums[i]=1,同样,2区后移一个位置,给新来的1腾地方。前面的0区无影响。(评论区某位大佬的理解)
这个里面设置了三个指针,第一个指针nums0是针对的整个零区间,后面两个指针同理,然后当遍历到0的时候,两个指针都往后面挪动一位,腾出一个位置给0放,然后nums0往后移动,当遍历到1的时候,指向2的指针向后动一位,给1挪个位置,接下来同理;(自己的理解);
接下来是官方解答的第三个双指针:
class Solution {
public:
void sortColors(vector<int>& nums) {
int n = nums.size();
int p0 = 0, p2 = n - 1;
for (int i = 0; i <= p2; ++i) {
while (i <= p2 && nums[i] == 2) {
swap(nums[i], nums[p2]);
--p2;
}
if (nums[i] == 0) {
swap(nums[i], nums[p0]);
++p0;
}
}
}
};
附上官方解答的链接:https://leetcode-cn.com/problems/sort-colors/solution/yan-se-fen-lei-by-leetcode-solution/