BFS算法示例 - 解開(kāi)密碼鎖的最少次數(shù)

概念

BFS(廣度優(yōu)先搜索)是最簡(jiǎn)便的圖的搜索算法之一馏颂,這一算法也是很多重要的圖的算法的原型蹬跃。

BFS算法的核心思想就是把一些問(wèn)題抽象成圖.

BFS相對(duì)DFS最主要的區(qū)別是: BFS找到的路徑一定是最短的,但代價(jià)是空間復(fù)雜度比DFS大很多.

BFS常出現(xiàn)的場(chǎng)景: 問(wèn)題的本質(zhì)就是讓你在一幅圖中找到從起點(diǎn) start 到終點(diǎn) target的最近距離,BFS算法其實(shí)就是在干這事.

一般來(lái)說(shuō)在找最短路徑的時(shí)候用BFS,其他時(shí)候還是用DFS多一些.

傳統(tǒng)的BFS框架是從起點(diǎn)開(kāi)始向四周擴(kuò)散,遇到終點(diǎn)時(shí)停止;而雙向BFS則是從起點(diǎn)和終點(diǎn)同時(shí)開(kāi)始擴(kuò)散,當(dāng)兩邊有交集的時(shí)候停止.

使用雙向BFS的前提是,必須提前知道終點(diǎn)在哪里.

無(wú)論傳統(tǒng)BFS還是雙向BFS,無(wú)論做不做優(yōu)化,從Big O 的衡量標(biāo)準(zhǔn)看,空間復(fù)雜度都是一樣的.


例題: 打開(kāi)密碼鎖

有一個(gè)帶四個(gè)圓形撥輪的轉(zhuǎn)盤(pán)鎖,每個(gè)撥輪都有0-9共10個(gè)數(shù)字,
每個(gè)撥輪可以上下旋轉(zhuǎn): 例如把9變成0, 0變成9,每次旋轉(zhuǎn)只能將一個(gè)撥輪旋轉(zhuǎn) 一下

代碼(python)

import copy
from rich.console import Console
from rich import print

console = Console()  
res  = []

#~ 解開(kāi)密碼鎖的最少次數(shù)


# 將密碼向上撥動(dòng)一次
def plusOne(s,j):
    ch = []
    for i in s:
        ch.append(i)

    if ch[j] == '9':
        ch[j] = str(0)
    else:
        ch[j] = str(int(ch[j]) + 1  )
        
    # print(ch)    
    res = ''        
    for i in ch:
        res += i 
    return res 

# 將密碼向下?lián)軇?dòng)一次
def minusOne(s,j):
    ch = []
    for i in s:
        ch.append(i)

    if ch[j] == '0':
        ch[j] = str(9)
    else:
        ch[j] = str(int(ch[j]) - 1  )
        
    res = ''        
    for i in ch:
        res += i 
    return res 
                
# 傳統(tǒng)BFS,從起點(diǎn)出發(fā)擴(kuò)散
def openLock(deadends,target):
    
    #記錄需要跳過(guò)的密碼
    deads = [] 
    for i in deadends:
        deads.append(i)
        
    #記錄已經(jīng)窮舉過(guò)的密碼,防止走回頭路
    visited = []
    q = []
    
    #從起點(diǎn)開(kāi)始啟動(dòng)廣度優(yōu)先搜索
    step = 0
    q.append("0000")
    visited.append("0000")
    
    while(q != None):
        sz = len(q)
        #將當(dāng)前隊(duì)列中的所有節(jié)點(diǎn)向周?chē)鷶U(kuò)散
        for i in range(sz):
            cur = q.pop(0)
            print(cur)
            
            #判斷密碼是否合法,是否到達(dá)終點(diǎn)
            if cur in deads:
                continue
            
            if cur  == target:
                return step
            
            # 將一個(gè)節(jié)點(diǎn)的未遍歷相鄰節(jié)點(diǎn)加入隊(duì)列
            for j in range(4):
                up = plusOne(cur,j)
                if up not in visited:
                    q.append(up)
                    visited.append(up)
                      
                down =  minusOne(cur,j)
                if down not in visited:
                    q.append(down)
                    visited.append(down)

        step += 1           
                    
    return -1                

# 雙向BFS                    
def both_openLock(deadends,target):
    
    #記錄需要跳過(guò)的密碼
    deads = [] 
    for i in deadends:
        deads.append(i)
        
    #記錄已經(jīng)窮舉過(guò)的密碼,防止走回頭路
    visited = []
    q1 = []
    q2 = []
    
    #初始化起點(diǎn)和終點(diǎn)
    q1.append("0000")
    q2.append(target)
    
    step = 0
    
    while(q1 != None and q2 != None):
        print('q1 is ' + str(q1))
        print('q2 is ' + str(q2))
        temp = []
        for cur in q1:
            if cur in deads:
                continue
            if cur in q2:
                return step
            visited.append(cur)
            
            for j in range(4):
                up = plusOne(cur,j)
                if up not in visited:
                    temp.append(up)
                      
                down =  minusOne(cur,j)
                if down not in visited:
                   temp.append(down)
    
        step += 1
        print('temp is '+ str(temp))
        q1 = q2
        q2 = temp
    
              
                    
    return -1                


deadends = ["0007","5678"]
target = "2222"    
    
res =   both_openLock(deadends,target)  
print(res)




Flutter 寫(xiě)的app, 需要源碼可以私信~~

最好的筆記軟件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末匿乃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子除呵,更是在濱河造成了極大的恐慌燎窘,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異根盒,居然都是意外死亡钳幅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)炎滞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)敢艰,“玉大人,你說(shuō)我怎么就攤上這事册赛∧频迹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵森瘪,是天一觀的道長(zhǎng)牡属。 經(jīng)常有香客問(wèn)我,道長(zhǎng)扼睬,這世上最難降的妖魔是什么逮栅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮窗宇,結(jié)果婚禮上证芭,老公的妹妹穿的比我還像新娘。我一直安慰自己担映,他們只是感情好废士,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蝇完,像睡著了一般官硝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上短蜕,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天氢架,我揣著相機(jī)與錄音,去河邊找鬼朋魔。 笑死岖研,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的警检。 我是一名探鬼主播孙援,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扇雕!你這毒婦竟也來(lái)了拓售?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镶奉,失蹤者是張志新(化名)和其女友劉穎础淤,沒(méi)想到半個(gè)月后崭放,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸽凶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年币砂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玻侥。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡道伟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出使碾,到底是詐尸還是另有隱情蜜徽,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布票摇,位于F島的核電站拘鞋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏矢门。R本人自食惡果不足惜盆色,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祟剔。 院中可真熱鬧隔躲,春花似錦、人聲如沸物延。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叛薯。三九已至浑吟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耗溜,已是汗流浹背组力。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抖拴,地道東北人燎字。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阿宅,于是被迫代替她去往敵國(guó)和親候衍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • DFS V.S. BFS DFS(Deep First Search)深度優(yōu)先搜索:其實(shí)就是回溯算法 BFS(Br...
    茹憶小玉兒閱讀 3,173評(píng)論 0 2
  • 讀完本文家夺,你可以去力扣拿下如下題目: 111.二叉樹(shù)的最小深度[https://leetcode-cn.com/p...
    labuladong閱讀 538評(píng)論 0 5
  • BFS/DFS區(qū)別 DFS就是回溯算法脱柱,BFS找到的路徑一定是最短的,但代價(jià)就是空間復(fù)雜度比 DFS 大很多DFS...
    瑾瑾寶寶閱讀 7,666評(píng)論 0 0
  • 百度百科關(guān)于搜索算法的定義:搜索算法是利用計(jì)算機(jī)的高性能來(lái)有目的的窮舉一個(gè)問(wèn)題解空間的部分或所有的可能情況拉馋,從而求...
    WalkeR_ZG閱讀 1,148評(píng)論 0 7
  • 兩種算法比較 廣度優(yōu)先搜索一個(gè)圖的時(shí)候是按照樹(shù)的層次來(lái)搜索的榨为,(層次遍歷),隊(duì)列來(lái)實(shí)現(xiàn)煌茴,我們假設(shè)一個(gè)節(jié)點(diǎn)衍生出來(lái)的...
    會(huì)發(fā)光的二極管閱讀 15,958評(píng)論 0 7