1. 程式人生 > 其它 >leetcode 75. Sort Colors 顏色分類

leetcode 75. Sort Colors 顏色分類

一、題目大意

連結:https://leetcode.cn/problems/sort-colors

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

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

必須在不使用庫的sort函式的情況下解決這個問題。

示例 1:

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

示例 2:

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

提示:

  • n == nums.length
  • 1 <= n <= 300
  • nums[i] 為 0、1 或 2

進階:

  • 你可以不使用程式碼庫中的排序函式來解決這道題嗎?
  • 你能想出一個僅使用常數空間的一趟掃描演算法嗎?

二、解題思路

兩個思路,一是用桶排序,先統計頻率,再按key排序,最後提取結果。另一種思路,因為值的話就3個是已經確定的,遍歷陣列0往陣列最左邊放,2往最右邊放,遍歷完陣列就排好了。

三、解題方法

3.1 Java實現-桶排序

public class Solution {
    public void sortColors(int[] nums) {
        // 統計頻率
        Map<Integer, Integer> seqMap = new HashMap<>();
        for (int tmp : nums) {
            seqMap.put(tmp, seqMap.getOrDefault(tmp, 0) + 1);
        }

        // 按key排序
        PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<>((a, b) -> b.getKey() - a.getKey());
        for (Map.Entry<Integer, Integer> entry : seqMap.entrySet()) {
            priorityQueue.add(entry);
        }

        // 提取結果
        int idx = nums.length - 1;
        while (!priorityQueue.isEmpty()) {
            Map.Entry<Integer, Integer> entry = priorityQueue.poll();
            for (int i = 0; i < entry.getValue(); i++) {
                nums[idx--] = entry.getKey();
            }
        }
    }
}

3.2 Java實現-另一種思路

public class Solution2 {
    public void sortColors(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        // 注意結束條件是 i<=right
        for (int i = 0; i <= right; i++) {
            if (nums[i] == 0) {
                swap(nums, i, left++);
            } else if (nums[i] == 2) {
                // 注意此時i要呆在原地,因為for裡面會執行i++,此時做i--做消減
                swap(nums, i--, right--);
            }
        }
    }

    void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

四、總結小記

  • 2022/5/24 用固定的套路桶排序解題耗時2毫秒,用另一種思路耗時不到1毫秒,雖然耗時少但我們還要掌握固定套路。