1. 程式人生 > >Leetcode演算法Java全解答--75. 顏色分類

Leetcode演算法Java全解答--75. 顏色分類

Leetcode演算法Java全解答–75. 顏色分類

文章目錄

題目

給定一個包含紅色、白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。

此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。

注意:
不能使用程式碼庫中的排序函式來解決這道題。

進階:

一個直觀的解決方案是使用計數排序的兩趟掃描演算法。
首先,迭代計算出0、1 和 2 元素的個數,然後按照0、1、2的排序,重寫當前陣列。
你能想出一個僅使用常數空間的一趟掃描演算法嗎?


示例:

輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]

想法

遍歷陣列,同時擁有三個遊標

left遊標用來表示0的分界點(左邊都是0),right遊標用來表示2的分界點(右邊都是2)

tmp遊標表示正在遊走的指標

當遇到數字2的時候,就將tmp和right的值交換,這時候right值為2,所以就把right往前移一位

當遇到數字0的時候,就將tmp和left的值交換,這時候left值為0,所以就把left往前移一位,同時tmp肯定不為2,所以往後移一位

當遇到數字0的時候,就將tmp++;

執行過程:

arr =  [2, 0, 2, 1, 1, 0],left = 0,right = 5,tmp = 0
第一輪:arr[tmp] == 2   >>  swap(arr[tmp],swap[right])  >> [0, 0, 2, 1, 1, 2],left = 0,right = 4,tmp = 0
第二輪:arr[tmp] == 0   >>  swap(arr[tmp],swap[left])  >> [0, 0, 2, 1, 1, 2],left = 1,right = 4,tmp = 1
第三輪:arr[tmp] == 0   >>  swap(arr[tmp],swap[left])  >> [0, 0, 2, 1, 1, 2],left = 2,right = 4,tmp = 2
第四輪:arr[tmp] == 2   >>  swap(arr[tmp],swap[right])  >> [0, 0, 2, 1, 1, 2],left = 2,right = 3,tmp = 2

結果

超過78%的測試案例

時間複雜度/空間複雜度:n/n

總結

程式碼

我的答案

public void sortColors(int[] nums) {
    int leftIndex = 0;
    int rightIndex = nums.length - 1;
    int tmpIndex = 0;
    // 0、2的時候進行交換
    while (tmpIndex < rightIndex) {
        int num = nums[tmpIndex];
        if (num == 1) {
            tmpIndex++;
        }
        if (num == 0) {
            swapArrByIndex(nums, tmpIndex, leftIndex);
            leftIndex++;
            tmpIndex++;
        }
        if (num == 2) {
            swapArrByIndex(nums, tmpIndex, rightIndex);
            rightIndex--;
        }
    }

}
private static void swapArrByIndex(int[] arr, int index1, int index2) {
    int tmp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = tmp;
}

大佬們的答案

/**************************************
 * 比我好的答案 better
 * 二次遍歷法
 * ***********************************/
public void better(int[] nums) {
    int a = 0, b = 0, c = 0;
    for (int n : nums) {
        if (n == 0) {
            a++;
        } else if (n == 1) {
            b++;
        } else if (n == 2) {
            c++;
        }
    }
    for (int i = 0; i < nums.length; i++) {
        if (a != 0) {
            nums[i] = 0;
            a--;
        } else if (b != 0) {
            nums[i] = 1;
            b--;
        } else if (c != 0) {
            nums[i] = 2;
            c--;
        }
    }
}

測試用例

@Test
public void test075() {
    // 建立測試案例

    int[] arr1 = new int[] { 2, 0, 2, 1, 1, 0 };

    // 測試案例期望值
    int[] expResult1 = new int[] { 0, 0, 1, 1, 2, 2 };

    // 執行方法
    Solution075 solution075 = new Solution075();
    solution075.sortColors(arr1);

    // 判斷期望值與實際值
    Assert.assertEquals(expResult1, arr1);
}

其他

程式碼託管碼雲地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git

檢視其他內容可以點選專欄或者我的部落格哈:https://blog.csdn.net/cmqwan

“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改

如有疑問請聯絡,聯絡方式:QQ3060507060