题目大意
对一个数组就地in-place
排序,即直接在原数组基础上进行。数组只包含0, 1, 2
三个元素。例如:
Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
进阶: 容易想到统计次数+重填
的两次遍历的方法,请你给出个一次遍历+常数空间
。
思路
因为只包含三个元素,因此可以采用不断交换的方式。遇到0
,就先和前面的2
交换,再和1
交换,遇到1
就和前面的2
交换。这样只需记录并更新已考察的元素中,1
和2
最早出现的位置即可。
另外,更新1, 2
位置时需要仔细考虑循环变量i
所指代的值。
代码
class Solution {
public:
void sortColors(vector<int>& nums) {
const int sz = nums.size();
int onei, twoi;
onei = twoi = -1;
for (int i = 0; i < sz; i++) {
const int tmp = nums[i];
if (tmp == 0) {
int j = i;
if (twoi != -1) {
j = twoi;
swap(nums[i], nums[twoi]);
if (nums[twoi + 1] == 2) twoi += 1;
else twoi = i;
}
if (onei != -1) {
swap(nums[j], nums[onei]);
if (nums[onei + 1] == 1) onei += 1;
else onei = j;
}
} else if (tmp == 1) {
if (onei == -1) onei = i;
if (twoi != -1) {
swap(nums[i], nums[twoi]);
if (onei > twoi) onei = twoi;
if (nums[twoi + 1] == 2) {
twoi += 1;
} else {
twoi = i;
}
}
} else {
if (twoi == -1) twoi = i;
}
}
}
};
总结
方法非常多。。