解題思路
思路二(all clear)
思路三(官方題解的繼續優化)
給定乙個陣列 nums,編寫乙個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。
必須在原陣列上操作,不能拷貝額外的陣列。
儘量減少操作次數。
既然題目簡單,那麼要求相對就要高一些。
乍眼一看,我第一反應是,寫乙個新的陣列,遍歷原陣列的時候,凡是讀到非零元素就在新陣列中新增該元素,然後剩下的填上0。可是後來一看題目說明,好傢伙,不能拷貝額外陣列,那就換個思路。
接下來想到的即就是,遍歷原本的陣列,一旦發現了0元素,就去找該0後面第乙個非零元素,然後交換彼此,如此重複,直到0後面找不到非零元素,那麼交換完成
首先寫乙個函式,檢查是否已經完成moving,返回第乙個0和該0之後第乙個非零元素的位置
def
check_finish
(self,nums)
:for i in
range
(len
(nums)):
if(nums[i]==0
):break
for j in
range
(i,len
(nums)):
if(nums[j]!=0
):return i,j,
false
return-1
,-1,
true
然後就是solution函式,用來交換:
def
movezeroes
(self,nums)
->
none
:print
(nums)
first_zero,first_nonezero_afterzero,is_finish = self.check_finish(nums)
while
not(is_finish)
: temp = nums[first_zero]
nums[first_zero]
= nums[first_nonezero_afterzero]
nums[first_nonezero_afterzero]
= temp
print
(nums)
first_zero, first_nonezero_afterzero, is_finish = self.check_finish(nums)
print
("moving finished"
)
我做測試,上來輸了乙個1,不小心按到回車,結果發現它開始迴圈了:
不出所料,再簡單的題也不會這麼容易就all clear:
leetcode給我拋了乙個十分長的字串,我就崩了
前者還是迭代的複雜度太高了,想辦法降低一下,這裡想到了雙指標,也就是官方給出的題解,官方講解放在這裡,即使我寫出來了也沒咋看明白他說的啥。
使用雙指標,左指標指向當前已經處理好的序列的尾部,右指標指向待處理序列的頭部。右指標不斷向右移動,每次右指標指向非零數,則將左右指標對應的數交換,同時左指標右移。
注意到以下性質:
左指標左邊均為非零數;
右指標左邊直到左指標處均為零。
因此每次交換,都是將左指標的零與右指標的非零數交換,且非零數的相對順序並未改變。
乙個指標用來尋找所有的非零元素,找到以後就按順序放在前面,如何按順序放在前面,就要靠另外乙個指標的移動來完成了這裡直接貼官方題解把,我寫的稍微有些冗餘(比如這個交換我每次都寫乙個新的變數用來交換)具體步驟如下:
左右指標都由最左側(0)開始
右指標開始向右移動,直到找到第乙個非零元素
左右指標指向的數值交換,左指標指向下乙個元素
右指標繼續向右,迴圈上述過程
直到右指標到達陣列末尾
def
movezeroes
(self, nums: list[
int])-
>
none
: n =
len(nums)
left = right =
0while right < n:
if nums[right]!=0
: nums[left]
, nums[right]
= nums[right]
, nums[left]
left +=
1 right +=
1
執行結果:
這裡既然後面都是0,官方題解的交換也就沒有必要了,也就是直接num[left]=num[right]即可,剩下的填0就完事了
def
movezeroes
(self, nums: list[
int])-
>
none
: n =
len(nums)
left = right =
0while right < n:
if nums[right]!=0
: nums[left]
= nums[right]
left +=
1 right +=
1for i in
range
(left,n)
: nums[i]
=0
執行結果:
雖然說時間是一樣的,但是記憶體少用了0.1mb啊,少一點是一點。
由於這道題簡單,我就多寫了個優化
hihoCoder每週一題
時間限制 10000ms 單點時限 1000ms include include include include includeusing namespace std int n,m define max 26 struct trie trie void createtrie char str el...
每週一題(1)
把2019分解成3個各不相同的正整數之和,並且要求每個正整數都不包含數字2和4.一共有多少種不同的分割方法。注意交換3個整數的順序被視為同一種方法1,例如1000 1001 18和1001 1000 18被視為同一種。這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果為乙個整數,在提交答案...
每週一題 4
如圖p1.png所示的螺旋折線經過平面上所有整點恰好一次。對於整點 x,y 我們定義它到原點的距離dis x,y 是從原點到 x,y 的螺旋折線段的長度。例如dis 0,1 3,dis 2,1 9 給出整點座標 x,y 你能計算出dis x,y 嗎?輸入格式 x和y對於40 的資料,1000 x,y...