75. [双指针][排序]颜色分类
75. 颜色分类
方法一:计数排序
统计数字\(0、1、2\)的个数,依次修改即可。
class Solution {
public void sortColors(int[] nums) {
// Arrays.sort(nums); // 双基准快排
int n = nums.length;
int cnt0 = 0, cnt1 = 0;
for(int i = 0; i < n; i++){
if(nums[i] == 0){
cnt0++;
} else if(nums[i] == 1){
cnt1++;
}
}
for(int i = 0; i < cnt0; i++){
nums[i] = 0;
}
for(int i = cnt0; i < cnt0 + cnt1; i++){
nums[i] = 1;
}
for(int i = cnt0 + cnt1; i < n; i++){
nums[i] = 2;
}
}
}
方法二:双指针
我们可以设置双指针,初始化时分别指向头和尾,在遍历过程中,把\(0\)放到数组的左边,把\(1\)放到数组的右边。
p1指针是从右向左移动的,当遍历为止超过了p1,循环就应该终止了。
p1指针在遍历时还会遇到一个问题,就是当 \(nums[i]\) 与 \(nums[p1]\)进行交换后,新的\(nums[i]\)仍然可能为2,如果此时我们直接进行下一次遍历,势必会得到错误答案。因此,当我们找到\(2\)时,应该不断地将其与\(nums[p1]\)进行交换,直到新的\(nums[i]\)不为\(2\)。
// 执行耗时:0 ms,击败了100.00% 的Java用户
// 内存消耗:37.4 MB,击败了44.59% 的Java用户
class Solution {
public void sortColors(int[] nums) {
int n = nums.length;
int p0 = 0, p1 = n - 1;
for(int i = 0; i < n ; i++){
while(i < p1 && nums[i] == 2){
nums[i] = nums[p1];
nums[p1] = 2;
p1--;
}
if (nums[i] == 0){
nums[i] = nums[p0];
nums[p0] = 0;
p0++;
}
}
}
}

浙公网安备 33010602011771号