leetcode BFS求解的幾道題

2021-10-14 12:14:32 字數 3052 閱讀 4646

題目:在乙個 n × n 的方形網格中,每個單元格有兩種狀態:空(0)或者阻塞(1)。返回這條從左上角到右下角的最短暢通路徑的長度。如果不存在這樣的路徑,返回 -1 。

設 d

id_i

di​ 表示第 i 個節點與根節點的距離,推導出乙個結論:對於先遍歷的節點 i 與後遍歷的節點 j,有 di≤

dj

d_i \le d_j

di​≤dj

​。利用這個結論,可以求解最短路徑等 最優解 問題:第一次遍歷到目的節點,其所經過的路徑為最短路徑。

定義佇列:bfs用佇列queue實現

向八個方向延展,延展的時候要將被延展的點標記為visited=1(即備忘錄)

其中,八個方向(dx

,dy)

=(−1

,−1)

,(−1

,0),

(−1,

1),(

0,−1

),(0

,1),

(1,−

1),(

1,0)

,(1,

1)

(dx,dy)=(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)

(dx,dy

)=(−

1,−1

),(−

1,0)

,(−1

,1),

(0,−

1),(

0,1)

,(1,

−1),

(1,0

),(1

,1)因此,座標位置和已走過的步數可以寫成乙個三維陣列

定義邊界條件:

① 矩陣為空,此時不存在路徑

② ( 0,

0),(

n−1,

n−1)

(0,0), (n-1,n-1)

(0,0),

(n−1

,n−1

)處的值為1(阻塞),此時不存在路徑

將起始位置加入到佇列中,同時更新備忘錄,即佇列queue初始化為[(0

,0,1

)]

[(0,0,1)]

[(0,0,

1)]

def

shortestpathbinarymatrix

(self, grid: list[list[

int]])

->

int:

n =len(grid)

ifnot grid or grid[0]

[0]==

1or grid[n-1]

[n-1]==

1:#定義邊界條件

return-1

if n<=2:

return n

queue =[(

0,0,

1)] grid[0]

[0]=

1#更新備忘錄

while queue:

#說明還有路可走

x,y,k = queue.pop(0)

for dx,dy in[(

-1,-

1),(

-1,0

),(-

1,1)

,(0,

-1),

(0,1

),(1

,-1)

,(1,

0),(

1,1)

]:if x+dx == n-

1and y+dy==n-1:

return k+

1elif

0<=x+dx<=n-

1and

0<=y+dy<=n-1:

#延展的方向沒有出界

if grid[x+dx]

[y+dy]==0

: (x+dx,y+dy,k+1)

) grid[x+dx]

[y+dy]=1

#更新備忘錄

#無路可走返回-1

return

-1

題目:給定正整數 n,找到若干個完全平方數(比如 1, 4, 9, 16, …)使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。
使組成和的完全平方數的個數最少,相當於找湊齊和的最短路徑,這是乙個最優解問題。

1.定義佇列:bfs用佇列queue實現,佇列中存放二元陣列(數,已分解的次數)。即數和走過的路徑組成的陣列。

2.如何將給定的正整數逐個分解乘完全平方數?

逐一分解=做減法,減數=i*i(完全平方數),餘數是target,如此得到多對完全平方數和餘數。接下來檢視餘數中是否在備忘錄**現過,如果餘數(即分解出乙個完全平方數後剩下的數)在備忘錄裡,那麼說明此時的這條路徑一定比第一次放入這個餘數的路徑長,並不是最優解,捨棄!!

3.終止條件:餘數為0

def

numsquares

(self, n:

int)

->

int:

#bfs

queue =

(n,0))

#需要分解的數,step

visited =

set(

)while queue:

#正整數n沒有被分解完

num,step = queue.pop(0)

targets =

[num-i*i for i in

range(1

,int

(math.sqrt(num)+1

))]for target in targets:

if target ==0:

#正整數n被分成若干個完全平方數

return step+

1elif target not

in visited:

(target,step+1)

) visited.add(target)

return

0

LeetCode BFS解決的題目

一.130 surrounded regions 題目 解法 這道題的意思是將所有被x包圍的o都變為x 邊緣的不算 我們可以維護乙個佇列,先把四周的o的位置放進佇列中,並把這個位置的值變為y。然後每次從佇列中拿出乙個位置,把這個位置四周為o的位置的值變為y,再把這個位置放進佇列 為什麼要先變值再進佇...

LeetCode BFS 刪除無效的括號

刪除最小數量的無效括號,使得輸入的字串有效,返回所有可能的結果。說明 輸入可能包含了除 和 以外的字元。示例 輸入 輸出 輸入 a 輸出 a a 輸入 輸出 class solution if isvalid s return queueq unordered setlookup 記錄字串是否被訪問...

2014 今天星期幾(暴力求解)

題目描述 小明是個馬大哈,經常忘了,今天是星期幾,於是他會去找三金問今天是星期幾。三金也忘記了,但是三金那裡有個記錄,為n天前是yyyy年mm月dd日星期w,問你今天的日期和星期幾。輸入第一行 t 表示以下有t組測試資料 1 t 8 對每組資料,佔一行 yyyymmdd w n 20000101 y...