题目描述
给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
代码
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
class Solution {//单指针 O(n);O(1)
public:
void sortColors(vector<int>& nums) {
int n = nums.size();
int ptr = 0;
for (int i = 0; i < n; ++i) {
if (nums[i] == 0) {
swap(nums[i], nums[ptr]);//将所有的0元素放在头部
++ptr;
}
}
for (int i = ptr; i < n; ++i) {
if (nums[i] == 1) {
swap(nums[i], nums[ptr]);将所有的元素1紧接着放进头部,最后只剩元素2了
++ptr;
}
}
}
};
//一次遍历,使用指针 p0来交换 0,p1来交换1。此时,p0和p1的初始值为0
class Solution1 {//同向双指针 O(n); O(1)
public:
void sortColors(vector<int>& nums) {
int n = nums.size();
int p0 = 0, p1 = 0;
for (int i = 0; i < n; ++i) {
if (nums[i] == 1) {
swap(nums[i], nums[p1]);
++p1;
}
else if (nums[i] == 0) {
swap(nums[i], nums[p0]);
if (p0 < p1) {//将1放在头部的末端
swap(nums[i], nums[p1]);
}
++p0;
++p1;//p0和p1都向后移动一个位置
}
}
}
};
//考虑使用指针 p0来交换 0,p2来交换 2。此时,p0的初始值仍然为 0,而 p2的初始值为 n−1。
class Solution2 {//相向双指针 O(N) O(1)
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) {//当p2指向2时,我们需要不断进行如下交换
swap(nums[i], nums[p2]);
--p2;//直到新的nums[i]!=2
}
if (nums[i] == 0) {
swap(nums[i], nums[p0]);
++p0;
}
}
}
};
vector<int> split(string params_str) {
vector<int> p;
while (params_str.find(",") != string::npos) {
int found = params_str.find(",");
p.push_back(stoi(params_str.substr(0, found)));
params_str = params_str.substr(found + 1);
}
p.push_back(stoi(params_str));
return p;
}
int main() {
//string input;
//getline(cin, input); // 读取整行输入,注意输入的是非递减数组
//vector<int> arr = split(input);
string input;
getline(cin, input);//[2,0,2,1,1,0]
input = input.substr(1, input.length() - 2); // Remove square brackets
istringstream iss(input);
vector<int> nums;
string numStr;
while (getline(iss, numStr, ',')) {
nums.push_back(stoi(numStr));
}
Solution1 a;
a.sortColors(nums);
string output = "";
for (int x : nums) {
output += to_string(x) + ',';
}
cout << "[" << output.substr(0, output.size() - 1) << "]";//[0,0,1,1,2,2]
}