LeetCode 75.颜色分类

菜鸡学习记录

题目链接:75. 颜色分类 - 力扣(LeetCode) (leetcode-cn.com)

看着蛮简单的问题,我一开始是准备对数字进行计数,然后返回一个新数组作为答案。但是题目中要求原地进行排序,这个要求我每次都想不明白。。

据力扣官方题解的说法,这是经典问题:荷兰国旗问题,由Dijkstra提出(或许这就是大佬)。

然后总结了以下两个做法:

法一:单指针

这个方法需要遍历两遍数组,第一遍把所有的0放到数组开头,然后确定下一次遍历的起始点;第二遍遍历把所有的1放到0后面,就完成了。

然后自己实现的代码如下:

public void sortColors1(int[] nums) {
    int length = nums.length;
    int index = 0;
    //将所有的0放到最开始
    for (int i = 0; i < length; i++) {
        if (nums[i] == 0) {
            int temp = nums[index];
            nums[index] = 0;
            nums[i] = temp;
            index++;
        }
    }
    //将所有的1放到0之后
    int start = index;
    for (int i = start; i < length; i++) {
        if (nums[i] == 1) {
            int temp = nums[index];
            nums[index] = 1;
            nums[i] = temp;
            index++;
        }
    }
}

法二:双指针

双指针只需要进行一次遍历即可,思路如下:

用指针p0来交换数字0,用指针p1来交换数字1,初始的时候,这两个指针都指向数组的位置0。指针i则用来遍历数组。

i找到数字1之后,就将nums[i]nums[p1]进行交换,同时将指针p1向后移动一个位置。

i找到数字0之后,就将nums[i]nums[p0]进行交换,同时将指针p0向后移动一个位置。

但是由于因为数字0的后面可能会有若干个1,出现这种情况的时候两个指针的关系为:p0<p1,则在进行交换的时候会把1交换过去。所以找到数字0的时候不仅要把p0向后移动,还要把p1向后移动。同时还要把num[i]nums[p1]进行交换。

public void sortColors(int[] nums) {
    int p0 = 0, p1 = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] == 1) {
            int temp = nums[p1];
            nums[p1] = 1;
            nums[i] = temp;
            p1++;
        }
        if (nums[i] == 0) {
            int temp = nums[p0];
            nums[p0] = 0;
            nums[i] = temp;
            if (p0 < p1) {
                int temp2 = nums[p1];
                nums[p1] = 1;
                nums[i] = temp2;
            }
            p1++;
            p0++;
        }
    }
}
posted @ 2022-01-11 17:23  ShaunY  阅读(26)  评论(0编辑  收藏  举报