1. 程式人生 > 其它 >線性一致性理解Linearizability

線性一致性理解Linearizability

技術標籤:指標leetcode指標

顏色分類

題目

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

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

示例 1:

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

示例 2:

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

示例 3:

輸入:nums = [0]
輸出:[0]

示例 4:

輸入:nums = [1]
輸出:[1]

提示:

n == nums.length

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

進階:

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

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sort-colors
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解題思路

排序函式

0、1、2 剛好是按照題目要求的紅色、白色、藍色順序,升序排列陣列即可得到。

優化

利用快速排序的特點,逐一對陣列元素進行判斷歸類,由於題目要求原地排序,於是採取兩兩交換的方法。

為實現一趟掃描陣列得到結果,需要特別地設定陣列兩邊的邊界, 0 一定是在最左邊部分,從左邊第一個位置開始,同理,出現 2 也是一定從最右邊部分的第一個位置開始, 1 出現在陣列的中間部分。所以兩邊初始設定指標 left、 right來控制邊界移動位置。

  1. 元素為 0 時:保證 0 從最左邊出現,交換此時 i 與 left 所指位置上的元素,left 指向 0 再向右移動,方便下次交換;
  2. 元素為 1 時:不影響 0 和 2 出現的位置,i 繼續向前遍歷;
  3. 元素為 2 時:保證 2 從最右邊出現,交換此時 i 與 right 所指位置上的元素,right 指向 2 再向左移動,當遇到與 i 相同時,表示結束。

提交程式碼

排序函式

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
nums.sort()

結果
在這裡插入圖片描述

優化

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        left = 0
        right = len(nums)
        i = 0
        while i < right:
            if nums[i] == 0:
                nums[i],nums[left] = nums[left],nums[i]
                left += 1
                i += 1
            elif nums[i] == 1:
                i += 1
            else:
                right -= 1
                nums[i],nums[right] = nums[right],nums[i] 
                 

結果
在這裡插入圖片描述

總結

  1. 優化時首先直接採用 for 迴圈,導致只能保證最左邊的元素為 0 ,出現的結果 1 和 2 往往是顛倒的順序,沒有將 i 和 right 的關係聯絡起來;
  2. while迴圈的優勢在於方便控制 i 的變化,分三種情況可以看出,當出現 2 時 i 不會遞增;
  3. 雙指標甚至多指標的思維實踐更加熟練,較之前有進步。