【LeetCode 中等題】39-顏色分類
阿新 • • 發佈:2019-01-07
題目描述:給定一個包含紅色、白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。
注意:
不能使用程式碼庫中的排序函式來解決這道題。
示例:
輸入: [2,0,2,1,1,0] 輸出: [0,0,1,1,2,2]進階:
- 一個直觀的解決方案是使用計數排序的兩趟掃描演算法。
首先,迭代計算出0、1 和 2 元素的個數,然後按照0、1、2的排序,重寫當前陣列。- 你能想出一個僅使用常數空間的一趟掃描演算法嗎?
解法1。必須原地更改陣列,新建陣列不行,輸出不改變,按照進階1的思路如下
class Solution(object): def sortColors(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ if not nums: return cnt = [0]*3 for i in nums: cnt[i] += 1 index = 0 for i in range(3): for j in range(cnt[i]): nums[index] = i index += 1
解法2。按照進階2的要求只遍歷一遍陣列,還好這道題只有3個值,所以相當於我們要把0搬到陣列最前面,2搬到陣列最後面,1若在中間就維持不變。用左右雙指標,左指標存放0,右指標存放2,遇到1跳過。
class Solution(object): def sortColors(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ if not nums: return l = 0 r = len(nums)-1 i = 0 while i <= r: # 注意這個地方用while不用for,for中i是自加,但i的值在迴圈體改變了,比較模糊 if nums[i] == 0: tmp = nums[i] nums[i] = nums[l] nums[l] = tmp l += 1 elif nums[i] == 2: tmp = nums[i] nums[i] = nums[r] nums[r] = tmp r -= 1 i -= 1 i += 1
解法3。同樣只遍歷1遍陣列,k的作用是記錄截止目前遍歷過的數字個數,j記錄的是0和1的個數,i記錄的是0的個數,所相當於截至i全是0,然後剩下截至j全是1,然後再剩下截至k全是2,如是
class Solution(object):
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
if not nums:
return
i, j, k = -1, -1, -1
for n in nums:
if n == 0:
i += 1
j += 1
k += 1
nums[k] = 2
nums[j] = 1
nums[i] = 0
elif n == 1:
j += 1
k += 1
nums[k] = 2
nums[j] = 1
elif n == 2:
k += 1
nums[k] = 2