移動零(簡單) 力扣每週一題

2021-10-10 15:41:32 字數 3769 閱讀 3829

解題思路

思路二(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...