Day18 機械人的運動範圍

2021-10-18 23:09:00 字數 4118 閱讀 6550

題目:

地上有乙個m行n列的方格,從座標 [0,0] 到座標 [m-1,n-1] 。乙個機械人從座標 [0, 0] 的格仔開始移動,它每次可以向左、右、上、下移動一格(不能移動到方格外),也不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 [35, 37] ,因為3+5+3+7=18。但它不能進入方格 [35, 38],因為3+5+3+8=19。請問該機械人能夠到達多少個格仔?

leetcode原題鏈結

思路:

dfs+剪枝,類似《矩陣中的路徑》

思路參考

定義兩個子函式

**:

class

solution

:def

movingcount

(self, m:

int, n:

int, k:

int)

->

int:

defnowsum

(m,n)

:#當前座標(m,n)的數字之和

p,q=

len(

str(m)),

len(

str(n)

) s=

0for i in

range

(p-1,-

1,-1

):s+=m//(10

**i)

m=m%(10

**i)

#此時的s是m的數字和

for i in

range

(q-1,-

1,-1

):s+=n//(10

**i)

n=n%(10

**i)

return s#此時s是m和n的數字之和

defdfs

(m,n,visit,k,i,j):if

not0

<= i < m or

not0

<= j < n:

return

0#索引越界

elif nowsum(i,j)

>k:

return

0#數字和大於k,不符合要求

elif

(i,j)

in visit:

return

0#該格已被訪問過,不符合要求

(i,j)

)return

1+dfs(m,n,visit,k,i +

1, j)

+ dfs(m,n,visit,k,i -

1, j)

+ dfs(m,n,visit,k,i, j +1)

+ dfs(m,n,visit,k,i, j -1)

visit=

list()

return dfs(m,n,visit,k,0,

0)

優化

由於機械人的起始位置是座標為[0, 0]的點,即左上角,所以僅考慮向下和向右的移動方向即可 ,優化後執行時間減半,記憶體消耗明顯減少

return

1+dfs(m,n,visit,k,i +

1, j)

+ dfs(m,n,visit,k,i, j +

1)

錯誤**:

錯誤在於,當出現第乙個不符合要求的格仔時【i=0,j=5】執行continue【結束本次迴圈,直接進行下一次迴圈的判斷條件】,只結束了本次迴圈,仍會對下乙個元素【i=0,j=5】進行判斷,繼續遍歷直至【i=10,j=0】,判斷發現數字和小於k,count執行+1,實際上,機械人無法移動至該方格

class

solution

:def

movingcount

(self, m:

int, n:

int, k:

int)

->

int:

defnowsum

(m,n)

:#當前座標(m,n)的數字之和

p,q=

len(

str(m)),

len(

str(n)

) p_sum=

0for i in

range

(p-1,-

1,-1

):p_sum+=m//(10

**i)

m=m%(10

**i)

#此時的p_sum是m的數字和

for i in

range

(q-1,-

1,-1

):p_sum+=n//(10

**i)

n=n%(10

**i)

return p_sum#此時p_sum是m和n的數字之和

count=

0for i in

range

(m):

for j in

range

(n):

if nowsum(i,j)

<=k:

count+=

1else

:continue

return count

示例2:m=38,n=15,k=9

放棄debug,採用遞迴來做【類似《矩陣中的路徑》】

count=

0for i in

range

(m):

for j in

range

(n):

if nowsum(i,j)

<=k:

count+=

1else

: j=

0break

if nowsum(i,j)

>k:

break

return count

額外學到的知識:

continue:用來結束當前當次迴圈,跳出迴圈體中下面尚未執行的語句,但不跳出當前迴圈。

for i in

range(4

):if i>1:

print

("執行了if語句"

)continue

print

("執行了後續語句"

)

i=0時,if判斷,false,不進入if內的語句,執行print("執行了後續語句")

i=1,if判斷,false,不進入if內的語句,執行print("執行了後續語句")

i=2,if判斷,true,進入if內語句,執行print("執行了if語句"),執行continue,結束本次i=2的迴圈,不再執行後續語句,進行下一次for迴圈遍歷(i=3)

i=3,if判斷,true,進入if內語句,執行print("執行了if語句"),執行continue,結束本次i=2的迴圈,不再執行後續語句,後續無 需執行的元素。

break:跳出(最內層)迴圈,不再執行

for i in

range(4

):if i>1:

print

("執行了if語句"

)break

print

("執行了後續語句"

)

i=0時,if判斷,false,不進入if內的語句,執行print("執行了後續語句")

i=1,if判斷,false,不進入if內的語句,執行print("執行了後續語句")

i=2,if判斷,true,進入if內語句,執行print("執行了if語句"),執行break,結束for迴圈。

機械人運動範圍

題目 地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 35,37 因為3 5 3 7 18。但是,它不能進入方格 35,38 因為3 5 3 8 1...

機械人運動範圍

地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 35,37 因為3 5 3 7 18。但是,它不能進入方格 35,38 因為3 5 3 8 19。請...

機械人的運動範圍

題目 地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。例如,當k為18時,機械人能夠進入方格 35,37 因為3 5 3 7 18。但是,它不能進入方格 35,38 因為3 5 3 8 1...