雙指針之顏色分類

題目描述

給定一個(gè)包含紅色、白色和藍(lán)色,一共 n 個(gè)元素的數(shù)組,原地對它們進(jìn)行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍(lán)色順序排列。

此題中,我們使用整數(shù) 0、 1 和 2 分別表示紅色、白色和藍(lán)色。

注意:
不能使用代碼庫中的排序函數(shù)來解決這道題。

示例

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

進(jìn)階

  • 一個(gè)直觀的解決方案是使用計(jì)數(shù)排序的兩趟掃描算法。
    首先,迭代計(jì)算出0、1 和 2 元素的個(gè)數(shù),然后按照0、1、2的排序,重寫當(dāng)前數(shù)組。
  • 你能想出一個(gè)僅使用常數(shù)空間的一趟掃描算法嗎?

問題分析


數(shù)組中只有三種顏色,0居左,2居右。我們維持兩個(gè)左右指針p0,p1,當(dāng)前位置指針是cur,如果當(dāng)前數(shù)是0,則將p0位置的數(shù)與cur位置的數(shù)交換,p0與cur同時(shí)往右移動(dòng);如果當(dāng)前數(shù)是1,則cur繼續(xù)往右移動(dòng);這樣我們可以保證數(shù)組的前面部分始終是0,1有序的。如果當(dāng)前數(shù)是2,則將cur位置的數(shù)與p1位置的數(shù)交換,但此時(shí)只需p1左移一位,cur不動(dòng),因?yàn)闊o法保證交換后cur左邊的數(shù)依然是0,1有序的。總之,我們要保持cur左邊的數(shù)都始終都是(0,1)有序時(shí),才移動(dòng)cur,這樣才能逐步把0置換到左邊,2置換到右邊,剩下的1自然就在中間。

代碼

class Solution:
    def swap(self, nums,a, b):
        tmp = nums[b]
        nums[b] = nums[a]
        nums[a] = tmp
        
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        p0 = 0
        p2 = n-1
        cur = 0
        while(cur<=p2):
            if nums[cur] == 0:
                self.swap(nums, p0, cur)
                p0 +=1
                cur +=1
            if nums[cur] == 2:
                self.swap(nums, p2, cur)
                p2 -=1
                # cur +=1
            else:
                cur += 1

對大小為N的數(shù)組進(jìn)行了一次遍歷,所以時(shí)間復(fù)雜度是O(N)。由于是原地置換,使用了常數(shù)空間,空間復(fù)雜度是O(1)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容