1. 程式人生 > 其它 >LeetCode 75.顏色分類

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++;
        }
    }
}