第一章 核心套路篇 之 BFS演算法套路框架

2021-10-17 05:05:24 字數 2923 閱讀 6554

bfs(breath first search)和dfs(depth first search) 是兩種十分常用的演算法,其中dfs演算法可以認為是回溯演算法

bfs演算法和核心就是將問題抽象成圖,從一點開始進行擴散,一般來說寫bfs的時候均使用佇列,每次將乙個結點周圍的所有結點加入到佇列中

bfs相對於dfs的主要區別是:bfs找到的路徑一定是最短的,但代價是空間複雜度比dfs高

func

bfs(start node, target node)

// 否則如果其相鄰結點沒有被訪問過就加入到佇列中

for_

, i :=

range n.adjacency }}

// 又訪問了一層

step++

}}

佇列是bfs中的核心資料結構,n.adjacency泛指與結點相鄰的其他結點,visited作用是為了防止走回頭路,大部分的時候是需要的,但是對於類似一般的二叉樹結構,沒有子節點到父結點的指標,不會走回頭路就不需要使用visited進行標記

輸入乙個二叉樹,計算它的最小高度,也就是根節點到葉子結點的短距離

那麼這道題應該如何套用bfs呢?該題中的開始結點為start,終點就是最靠近根節點的葉子結點,也就是左子樹為nil,右子樹也為nil

func

getminheight

(root *node)

int// 假設宣告乙個佇列

var q queue

// 將根節點加入到佇列中

q.push

(root)

depth :=

1for

!q.empty()

// 左節點

if n.left !=

nil// 右結點

if n.right !=

nil}

// 增加一層深度

depth ++

}return depth

}

當然其實求解二叉樹的最大高度也可以使用bfs進行求解,我們只要將佇列中的資料全部遍歷完,這樣我們肯定就遍歷了最後一層結點,題目可見 leetcode

下面是**:

func

maxdepth

(root *treenode)

int q :=

make([

]*treenode,1)

q[0]

= root

count :=

0for

len(q)

>

0if n.right !=

nil}

count ++

}return count

}

在**複雜問題之前,先回答下面的兩個問題:

1. 為什麼bfs可以找到最短距離,但是dfs不行?

在bfs中,只有當每乙個結點都向下移動一步的時候,才會使得depth加一,所以可以保證一旦找到乙個終點,那麼所需要的步數是最小的,bfs最壞的時間複雜度為o(n

)o(n)

o(n)

。dfs同樣可以求解這類問題,但是需要遍歷所有的路徑才能找到最短的路徑,雖然說dfs在big o衡量標準下最壞的時間複雜度都是o(n

)o(n)

o(n)

,但是bfs更加高效,我們可以認為,在求解的過程中,bfs走的是線,而dfs走的是點。

2. 既然bfs這麼好,那麼為啥要使用dfs?

bfs可以找到最短距離,但是空間複雜度相對而言比較高,而dfs的空間複雜度較低

一般而言,在求解最短路徑的時候使用bfs,其他時候更多的使用bfs

leetcode 752題

我們可以每乙個密碼看出乙個結點,每乙個密碼進行變化之後可以衍生出其他的不同密碼,乙個結點可以連線到其他另外8個頂點,整個求解過程就是乙個圖的遍歷問題,我們要想獲取到最小的次數,那麼可以使用bfs來進行求解。

在這個題目中,開始結點就是0000,而終點就是所給的target,但是這個不想二叉樹,有可能會走回頭路,所以需要使用visited進行

**如下

func

openlock

(deadends [

]string

, target string

)int

if cur == target

for i :=

0; i <

4; i++

d :=

down([

]byte

(cur)

, i)

if!visited[d]}}

count++

}return-1

}func

isdead

(deadends [

]string

, lock string

)bool

}return

false

}// 向上撥動一格

func

up(s [

]byte

, i int

)string

else

return

string

(s)}

// 向下撥動一格

func

down

(s [

]byte

, i int

)string

else

return

string

(s)}

這道題還可以使用雙向bfs進行求解,具體見: bfs框架,這裡不做講

第一章 核心套路篇 之 滑動視窗演算法框架

滑動視窗演算法的主要 框架如下 s 是所給的字串或者其他陣列 t 是目標值 func slidingwindow s,t string left,right 0,0 valid 0 s不一定是字串,還可以是其他型別的陣列 如果右指標還沒有到達s的終點 for right len s 下面以例子來進行...

第一章 Linux核心簡介

unix 中所有的東西都被當作檔案對待。unix 核心和相關的系統工具軟體是用 c 語言編寫而成。unix 程序建立非常迅速,並且有乙個非常獨特的 fork 系統呼叫。linux 是非商業化的產品,它使用 gnu 的 general public license gpl 第二版本作為限制條款。執行於...

第一章 Linux核心簡介

1.linux是類unix系統,但他不是unix。儘管linux借鑑了unix的許多設計並且實現了unix的api 由posix標準和其他single unix specification定義的 但linux沒有像其他unix變種那樣直接使用unix的原始碼。2.linux系統的基礎是核心 c庫 工...