- 初始解法
最開始的想法是用三個指針來解決該問題,分別是left, right和tmp。其中
也就是left和right代表着最長0串或2串的邊界。tmp指針指向當前正在處理的位置。
而出於對於特殊情況的考慮,先判斷nums是否爲空,若爲空,則直接返回。
接下來爲了達到(1)(2)式的要求,先用循環將left和right的初始位置設置好。
while left < right and nums[left] == 0:
left += 1
while left < right and nums[right] == 2:
right -= 1
此時就可以開始處理left和right之間的數組。處理方式就是用tmp指針掃一遍數組,將掃到的0放到左邊,掃到的2放到右邊。具體的處理方式是,如果掃到0,那麼就將nums[left]與nums[tmp]替換,同時將left指針右移一格;如果掃到2,那麼就考察nums[right]的值,如果值爲0,那麼就可以在更新nums[right]的值的同時更新nums[left]的值,將left和right的值同時移動,如果值不爲0,那麼就將nums[left]與nums[tmp]替換,right左移一格。此處需要注意,由於left在tmp左邊,所以nums[left]只有可能是1,所以掃到0的時候不用考察nums[left]的值就可以直接替換。
在進行如上更新後,可能此時的nums[left]爲0,nums[right]爲2,所以又要進行left和right的更新,使得此時的left和right達到(1)(2)式的要求。而tmp也要根據left進行更新,如果left更新後到了tmp的右邊,那麼就將tmp更新爲此時的left。
tmp指針掃完left和right之間的數組,也就是tmp>right的時候,整個算法就已經完成了。就地排序完成。
總體代碼如下:
class Solution:
def sortColors(self, nums: List[int]) -> None:
# empty list
if not nums:
return
l = len(nums)
right = l-1
left = 0
while left < right and nums[left] == 0:
left += 1
while left < right and nums[right] == 2:
right -= 1
tmp = left
while tmp <= right:
if nums[tmp] == 2:
if nums[right] == 0:
nums[tmp] = nums[left]
nums[left] = 0
nums[right] = 2
left += 1
right -= 1
else:
nums[tmp] = nums[right]
nums[right] = 2
right -= 1
else:
if nums[tmp] == 0:
nums[tmp] = nums[left]
nums[left] = 0
left += 1
while left < right and nums[left] == 0:
left += 1
while left < right and nums[right] == 2:
right -= 1
tmp = max(tmp+1, left)
return
- 官方解法
在看到官方解法後,覺得自己的方法雖然時間複雜度和空間複雜度並沒有特別大的劣勢,但是代碼不夠簡潔,思路不夠清晰,所以又參考了官方代碼改了一版答案。
官方代碼的思路是也是用三個指針,分別是left、right和tmp,但是left、right需要滿足的條件和我的代碼的條件不同。
官方解法對nums[left]和nums[right]沒有要求,所以就不用寫那兩個循環。
思路依然是將0全都移到left指針左邊,2移到right指針右邊。將數組從頭到尾掃一遍,如果nums[tmp]爲0,就將nums[left]與nums[tmp]替換,將0移到left左邊,同時將left和tmp均向右移一格,如果nums[tmp]爲1,那麼就直接將tmp向右移一格,如果nums[tmp]爲2,就將nums[right]與nums[tmp]替換,同時將right向左移一格,將2移到right右邊,因爲nums[right]的值沒有被考察過,所以此時tmp不能向右移。
完整代碼:
class Solution:
def sortColors(self, nums: List[int]) -> None:
# empty list
if not nums:
return
l = len(nums)
right = l-1
left = 0
tmp = left
while tmp <= right:
if nums[tmp] == 0:
nums[tmp] = nums[left]
nums[left] = 0
tmp += 1
left += 1
elif nums[tmp] == 2:
nums[tmp] = nums[right]
nums[right] = 2
right -= 1
else:
tmp += 1
return