近半年經常刷題,也參加了同學們自行組織的刷題會,到寫這篇文章為止 leetcode 已經 ac 了 77 道題目了。時常的總結是必要的,而分享知識不僅能幫助自己樹立知識脈絡,更能幫助到大家,為學習演算法的同學們提供一種參考的思路。
廣度優先搜尋(bfs)是在搜尋中首先將所處位置的直接鄰居訪問一遍,再進入下一層重複之前操作的一種搜尋。這種演算法需要維護乙個佇列。佇列有著先進先出(first in first out)的性質。演算法的開始一般都是把根節點加入到空佇列中,然後開始乙個結束條件是隊列為空的迴圈。每一次迴圈中,演算法會取得佇列最前的乙個元素並且訪問它的所有鄰居。在訪問鄰居的同時,程式會把鄰居新增到佇列中。至此廣度優先搜尋就寫完了,程式會按照上述迴圈把能夠訪問到的節點都訪問一遍。
這種演算法可以應用在圖,也可以應用在樹上。下面我們來看幾道跟樹這種資料結構有關的題目。
leetcode 429 這道題是典型的廣度優先搜尋,要求按層遍歷樹。解答如下:
"""
# definition for a node.
class node(object):
def __init__(self, val, children):
self.val = val
self.children = children
"""class
solution
(object):
deflevelorder
(self, root)
:"""
:type root: node
:rtype: list[list[int]]
"""if root is
none
:return
queue =
[(root,0)
] result =
while queue:
node, level = queue.pop(0)
while
len(result)
<= level:
) result[level]
for child in node.children:
(child, level +1)
)return result
我們規定根節點是第 0 層,然後把節點和所在層級放在乙個 tuple 裡進隊。迴圈的終止條件是隊列為空,當佇列有元素時,隊頭出隊,我們對元素做一些處理,然後將它的子孫加入佇列。在這個問題中,對於元素的操作比較簡單,把它加入結果陣列中即可。當然,加入之前要保證陣列對應的位置有陣列存在(結果是乙個包含陣列的陣列),不然會丟擲索引越界的異常。
leetcode 103 是一道中等難度的題目,要求交叉遍歷二叉樹。交叉的意思是從根節點開始,根節點那層從左到右遍歷,下一層從右到左,再下一層從左到右,依次迴圈直到最後一層,期間忽略 null.
# definition for a binary tree node.
# class treenode(object):
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class
solution
(object):
defzigzaglevelorder
(self, root)
:"""
:type root: treenode
:rtype: list[list[int]]
"""if root is
none
:return
queue =
[(root,0,
true)]
result =
while queue:
node, level, left_to_right = queue.pop(0)
while
len(result)
<= level:
) nodes_on_same_level =
[node]
while
len(queue)
>
0and queue[0]
[1]== level:0)
[0])
for n in nodes_on_same_level:
if n.left:
(n.left, level +1,
not left_to_right)
)if n.right:
(n.right, level +1,
not left_to_right)
)if left_to_right:
for n in nodes_on_same_level:
result[level]
else
:for i in
range
(len
(nodes_on_same_level)-1
,-1,
-1):
n = nodes_on_same_level[i]
result[level]
return result
題目依舊是要求按層遍歷,所以廣度優先搜尋仍然是我選用的方法。於是讀者可以發現本題解法和上一題有著很類似的結構,也有人稱之為「套公式」。不同的第一處在於佇列中的 tuple 現在有三個元素了,增加了末尾的乙個布林型別。該布林變數值為 true 的時候說明當前層級需要從左往右遍歷,反之從右往左。在迴圈中,程式一次性將一層的節點全部找出,按照布林變數指定的順序新增到結果陣列中。剩下的工作就是將子節點進隊,和上一題同樣的是層級要加 1,不同的是要將布林變數扭轉後再存入佇列。 BFS廣度優先搜尋
廣度優先搜尋,利用佇列實現,結束標誌是隊列為空的時候 承接dfs的演算法實現的講例,對於迷宮問題我們也可以採取廣度優先搜尋實現 include iostream include cstdio include cstdlib using namespace std int map 55 55 int ...
bfs廣度優先搜尋
這一課我們來學習圖的另一種遍歷方法 廣度優先搜尋 breadth first search,簡稱 bfs 這是一種連通圖的常用遍歷策略,通常用於求起點到各點的最短路徑,以及求兩點之間的最優路徑等問題。首先我們先來看看廣度優先搜尋的具體方法吧 對於乙個連通圖,我們假設一開始所有頂點均未被訪問,廣度優先...
廣度優先搜尋bfs
bfs即廣度優先搜尋演算法,其是搜尋演算法中的一種。1.dfs常用於尋找是否存在解 其從a節點出發,選取乙個臨近點b,然後不斷深入,在搜尋完b的下屬節點 ehif 後,回到a再搜尋臨近a的c節點,以此類推。2.bfs則用於在最短的時間或最少的移動距離內找到解 其往往從a節點出發,搜尋周圍所有的圍繞節...