Loading

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++;
            }
        }
    }
}
posted @ 2020-10-24 11:01  上海井盖王  阅读(109)  评论(0)    收藏  举报