LeetCode廣度優先演算法的題

2021-09-05 10:44:19 字數 4030 閱讀 5095

真的坑,自己想完全沒想到,看了一些大神的部落格寫出來的。那個列表很坑,不能寫在一起。

但作為一名小白還是很欣慰的。

'''

給定乙個由 『1』(陸地)和 『0』(水)組成的的二維網格,計算島嶼的數量。

乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。

你可以假設網格的四個邊均被水包圍

'''# 考慮這個題目,計算島嶼數量,也就是單獨島嶼的數量,

# 兩個以上的1 連在一起的算是乙個島嶼,那麼也就是只要找到單獨一塊的島嶼就行了,

# 這樣就很好理解了!

lt1 =[[

1,1,

0,0,

0],[

0,1,

0,0,

1],[

0,0,

0,1,

1],[

0,0,

0,0,

0],[

0,0,

0,0,

1]]lt2 =[[

1,1,

1,1,

0],[

1,1,

0,1,

0],[

0,0,

0,1,

1],[

0,0,

0,0,

0],[

0,0,

0,0,

1]]class

solution

:def

munisland

(self, grid)

: n =

len(grid)

if n ==0:

return

'地圖為空'

m =len(grid[0]

)if m ==0:

return

'地圖為空'

# 當找到島嶼的時候就把下面變數自+1

res =

0# 開始遍歷尋找第乙個 1 ,(島嶼)

for i in

range

(n):

for j in

range

(m):

# 判斷是不是乙個島嶼

if grid[i]

[j]==1:

res = res +

1# 這個時候還要判斷與它連線在一起的1,

# 畢竟一家人要整整齊齊的,所以遞迴尋找連在一起的所有島嶼,

# 同時需要注意的是,乙個島嶼你只能遍歷一次,

# 所以打個標識,讓尋找到的島嶼變成0

self.change(grid, i, j)

return res

defchange

(self, grid, i, j)

: grid[i]

[j]=

0# 判斷這個島嶼上下左右的方向

# 判斷上方字元

if i >

0and grid[i -1]

[j]==1:

self.change(grid, i -

1, j)

# 判斷左方字元

if j >

0and grid[i]

[j -1]

==1: self.change(grid, i, j -1)

# 判斷下方字元

if i <

len(grid)-1

and grid[i +1]

[j]==1:

self.change(grid, i +

1, j)

# 判斷右方字元

if j <

len(grid[0]

)-1and grid[i]

[j +1]

==1: self.change(grid, i, j +1)

ss = solution(

)print

(ss.munisland(lt1)

)print

(ss.munisland(lt2)

)

import collections

class

solution

:'''

演算法思想:

這也是一道很有意思的題,其實本質就是個迷宮遍歷的問題,只不過相鄰位置不再是上下左右四個位置,

而是四位數字每個都加一減一,總共有八個相鄰的位置。與經典bfs遍歷迷宮解法唯一不同的就是找下乙個位置的地方,

這裡我們要遍歷四位數字的每一位,然後分別加1減1,我們用j從-1遍歷到1,遇到0跳過,也就是實現了加1減1的過程。

然後我們要計算要更新位上的數字,為了處理9加1變0,和0減1變9的情況,我們統一給該位數字加上個10,然後再加或減1,

最後再對10取餘即可。

如果此時新生成的字串等於target了,直接返回結果res,否則我們看如果該字串不在死鎖集合裡,

且之前沒有遍歷過,那麼加入佇列queue中,之後將該字串加入visited集合中即可。注意這裡在while迴圈中,

由於要一層一層的往外擴充套件

'''defopenlock

(self, deadends, target)

: deadset =

set(deadends)

if(target in deadset)or(

"0000"

in deadset)

:return-1

# 之前沒有遍歷過加入佇列之中

que = collections.deque(

)"0000"

)# 然後在把他加入集合裡面

visited =

set(

["0000"])

step =

0# 這個要一層層的向外擴張

while que:

# 每次迴圈尋找次數都會+1

step +=

1# 計算每次迴圈時,佇列中原書的個數

size =

len(que)

# 在新的元素基礎上開始遍歷

for i in

range

(size)

:# 依次取出 0 1 2 3 4 ... 賦值給point指標

point = que.popleft(

)# 第二次迴圈,給每個滾輪上面操作

for j in

range(4

):# 第三次迴圈,設定 +1, -1,讓每個滾輪加+、減一

for k in

range(-

1,2,

2):# 程式執行到這裡,point已經執行完畢了,也就是point就等於queue,這裡是把point賦給newpoint

newpoint =

[i for i in point]

# 讓這個新賦值的佇列中,給每個元素加減1操作,並且這裡有-1-9,10-0的轉換操作

newpoint[j]

=chr((

ord(newpoint[j])-

ord(

'0')

+ k)%10

+ord

('0'))

# 這裡把列表裡面['1','2','3','4']轉換為'1234'

newpoint =

"".join(newpoint)

# 判斷這個字串是不是目標字串

if newpoint == target:

return step

# 如果這個字串不再死鎖或者集合字串中, 就跳過這次迴圈

if(newpoint in deadset)

or(newpoint in visited)

:continue

# 把這個字串加入到佇列queue中

# 把這個字串加入到集合中

visited.add(newpoint)

return-1

a = solution(

)ret = a.openlock(

'1515'

,'1523'

)print

(ret)

廣度優先演算法 越獄

建築師麥可為了救含冤入獄的哥哥,自己也想辦法進了監獄。現在他找到了哥哥,想帶著哥哥越獄。可是監獄地形複雜,還有一道道的電網攔在面前。電網非常危險,不到無路可走,麥可都不想嘗試鑽過電網。請幫麥可兄弟設計一條穿過電網最少的路線。只能往相鄰的四個方向前進 第一行 n,表示地圖的大小 10 n 1000 接...

廣度優先遍歷演算法

廣度優先搜尋 也稱寬度優先搜尋,縮寫bfs 是連通圖的一種遍歷策略。因為它的思想是從乙個頂點v0v0開始,輻射狀地優先遍歷其周圍較廣的區域,因此得名。一般可以用它做什麼呢?乙個最直觀經典的例子就是走迷宮,我們從起點開始,找出到終點的最短路程,很多最短路徑演算法就是基於廣度優先的思想成立的。type ...

深度優先演算法和廣度優先演算法

圖形的深度優先搜尋法 void dfs int current 主程式 建立圖形後,將遍歷內容印出.void main 邊線陣列 int i for i 1 i 8 i creategraph node,20 建立圖形 printf 圖形的鄰接鍊錶內容 n for i 1 i 8 i printf ...