給定乙個包含紅色、白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。
注意:不能使用**庫中的排序函式來解決這道題。
示例:輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]
高階:乙個直觀的解決方案是使用計數排序的兩趟掃瞄演算法。
首先,迭代計算出0、1 和 2 元素的個數,然後按照0、1、2的排序,重寫當前陣列。
你能想出乙個僅使用常數空間的一趟掃瞄演算法嗎?
class
solution
:def
sortcolors
(self, nums: list[
int])-
>
none
:"""
do not return anything, modify nums in-place instead.
"""m =
len(nums)
num_sort =[0
for _ in
range(3
)]for num in nums:
num_sort[num]+=1
for index, count in
enumerate
(num_sort)
: n = count
while n>0:
n -=
1del nums[
0:m]
第二種思路:
迴圈不變數:宣告的變數在遍歷的過程中需要保持定義不變。
設計迴圈不變數的原則
說明:設計迴圈不變數的原則是 不重不漏。
len 是陣列的長度;
變數 zero 是前兩個子區間的分界點,乙個是閉區間,另乙個就必須是開區間;
變數 i 是迴圈變數,一般設定為開區間,表示 i 之前的元素是遍歷過的;
two 是另乙個分界線,我設計成閉區間。
如果迴圈不變數定義如下:
所有在子區間 [0, zero) 的元素都等於 0;
所有在子區間 [zero, i) 的元素都等於 1;
所有在子區間 [two, len - 1] 的元素都等於 2。
於是編碼要解決以下三個問題:
變數初始化應該如何定義;
在遍歷的時候,是先加減還是先交換;
什麼時候迴圈終止。
處理這三個問題,完全看迴圈不變數的定義。
編碼的時候,zero 和 two 初始化的值就應該保證上面的三個子區間全為空;
在遍歷的過程中,「下標先加減再交換」、還是「先交換再加減」就看初始化的時候變數在**;
退出迴圈的條件也看上面定義的迴圈不變數,在 i == two 成立的時候,上面的三個子區間就正好 不重不漏 地覆蓋了整個陣列,並且給出的性質成立,題目的任務也就完成了。
class
solution
:def
sortcolors
(self, nums: list[
int])-
>
none
:"""
do not return anything, modify nums in-place instead.
"""defswap
(nums,index1,index2)
: nums[index1]
,nums[index2]
=nums[index2]
,nums[index1]
size=
len(nums)
if size<2:
return
#0,1分界
zero=
0#1,2分界
two=size
#迴圈不變數
i=0while i < two:
if nums[i]==0
: swap(nums,i,zero)
i +=
1 zero +=
1elif nums[i]==1
: i +=
1else
: two -=
1 swap(nums, i, two)
leetcode刷題 75顏色分類
給定乙個包含紅色 白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色 白色 藍色順序排列。此題中,我們使用整數 0 1 和 2 分別表示紅色 白色和藍色。注意 不能使用 庫中的排序函式來解決這道題。示例 輸入 2,0,2,1,1,0 輸出 0,0,1,1,2,...
leetcode刷題之 75 顏色分類
class solution def sortcolors self,nums list int none do not return anything,modify nums in place instead.a nums.count 0 b nums.count 1 c nums.count 2...
LeetCode演算法題75 顏色分類解析
給定乙個包含紅色 白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色 白色 藍色順序排列。此題中,我們使用整數 0 1 和 2 分別表示紅色 白色和藍色。注意 不能使用 庫中的排序函式來解決這道題。示例 輸入 2,0,2,1,1,0 輸出 0,0,1,1,2,...