首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode 筆記:Sort Colors(顏色分類 / 荷蘭國旗問題)

     編輯:關於C++

一、題目描述

給定包含 0、1、2 的數組,原地排序使相同顏色相鄰,順序為 0、1、2。不得使用庫排序函數。
進階:能否一次遍歷、常數空間完成?

二、解題思路:計數排序(兩遍)

第一遍統計 0、1、2 的個數 cnt[3]。第二遍按順序覆寫數組:先寫 cnt[0] 個 0,再 cnt[1] 個 1,最後 cnt[2] 個 2。雖然兩遍,但代碼簡單,且只掃描數組兩次,符合「一次遍歷」的廣義理解(不交換元素)。

三、代碼實現(C++)

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int cnt[3] = {0};
        for (int x : nums) ++cnt[x];
        int idx = 0;
        for (int c = 0; c < 3; ++c)
            for (int i = 0; i < cnt[c]; ++i)
                nums[idx++] = c;
    }
};

四、進階:單遍歷三向切分(Dutch National Flag)

維護三個指針:zero 指向下一個 0 的位置,two 指向下一個 2 的位置,i 遍歷。
- nums[i]==0:交換 nums[i++] 和 nums[zero++]
- nums[i]==2:交換 nums[i] 和 nums[two--](i 不動,需重新檢查換來的值)
- nums[i]==1:i++

void sortColors(vector<int>& nums) {
    int zero = 0, two = nums.size() - 1, i = 0;
    while (i <= two) {
        if (nums[i] == 0) swap(nums[i++], nums[zero++]);
        else if (nums[i] == 2) swap(nums[i], nums[two--]);
        else ++i;
    }
}

五、複雜度分析

  • 計數法:時間 O(N),空間 O(1)
  • 三向切分:時間 O(N),空間 O(1),單遍歷

本題為荷蘭國旗問題經典變體,三向切分是標準最優解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved