題目:
地上有乙個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內的語句,執行break:跳出(最內層)迴圈,不再執行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的迴圈,不再執行後續語句,後續無 需執行的元素。
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...