日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

广度优先遍历算法-02合法的括号问题

發(fā)布時(shí)間:2024/4/11 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 广度优先遍历算法-02合法的括号问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

合法的括號(hào)

  • 簡(jiǎn)介
    • 比較基礎(chǔ)的BFS題目。
    • 注意,由于要對(duì)不合法的字符串最小步數(shù)刪減為合法的字符串,所以BFS合適。
    • 之所以選擇BFS,是因?yàn)橐祷氐慕Y(jié)果為刪減最小數(shù)目的括號(hào)后使字符串合法,“就近搜索顯然合適”。
  • 問(wèn)題描述
    • 給定一個(gè)字符串,字符串會(huì)出現(xiàn)字母和"(“以及”)",認(rèn)為左右括號(hào)匹配完全的字符串是合法的,不完全的通過(guò)刪除若干個(gè)括號(hào)得到合法字符串,現(xiàn)在要求移除最少數(shù)目的括號(hào),使得其合法,并返回所有合法字符串。
  • 問(wèn)題分析
    • 對(duì)于括號(hào)匹配的問(wèn)題,最先想到的應(yīng)該是。常規(guī)的操作是左括號(hào)入棧,遇到右括號(hào)將一個(gè)左括號(hào)出棧。最后棧空,則括號(hào)字符串合法。但是,對(duì)于最短路徑這類題,廣度優(yōu)先遍歷不僅可以找到合法字符串?dāng)?shù)目,還可以找到找到的字符串序列具體情況,所以BFS更加合適一些。
    • 舉個(gè)例子
      • 假設(shè)字符串為"(a)(b))()",發(fā)現(xiàn)右括號(hào)有4個(gè),而左括號(hào)只有3個(gè),那么我們需要?jiǎng)h除一個(gè)右括號(hào)。
        • 這就是一個(gè)核心思路,當(dāng)左右括號(hào)不對(duì)等的時(shí)候應(yīng)該刪除差值數(shù)目的括號(hào)使得數(shù)目對(duì)等,將刪除之后合法的加入遍歷隊(duì)列。
        • 刪除第一個(gè)右括號(hào)得到"(a(b))()",刪除第二和第三個(gè)右括號(hào)得到"(a)(b)()",刪除第四個(gè)后不合法。(這里有兩個(gè)核心問(wèn)題,判斷合法和去重
    • 首先,如何判斷一個(gè)字符串是否合法。
      • 當(dāng)然可以使用之前所說(shuō)的棧,這畢竟是棧的典型應(yīng)用。
      • 其實(shí),為了節(jié)省內(nèi)存開(kāi)銷(xiāo),可以使用一個(gè)變量模擬棧,從頭到尾掃描字符串,遇到左括號(hào)變量加1,遇到右括號(hào)變量減1,一旦某一步變量小于0,這個(gè)字符串就是非法的;最后變量為0則合法。
      • 代碼
        • def is_valid(s):"""判斷是否括號(hào)合法:param s: :return: """count = 0for item in s:if item == "(":count += 1elif item == ")":count -= 1if count < 0:return Falsereturn count == 0
    • 其次,去重,每一層使用set即可。(不可層間)
    • BFS算法流程
      • 初始化隊(duì)列為空,將初始字符串加入隊(duì)列。
      • 每次從隊(duì)列取出一個(gè)字符串,判斷是否合法。
        • 如果合法,則加入結(jié)果集。(因?yàn)榇藭r(shí)最小刪除步數(shù)為0)
        • 如果不合法,找到左右括號(hào)的位置,刪除其。理論上對(duì)于N個(gè)括號(hào)的字符串,這一步得到N-1個(gè)字符串,由于去重,也可能小于這個(gè)數(shù)目。
        • 注意:每一次對(duì)當(dāng)前隊(duì)列判斷是否存在合法字符串,若這一層存在,則算法結(jié)束(因?yàn)樵偃コㄌ?hào)已經(jīng)不符合最少步數(shù)要求)。
    • 這個(gè)問(wèn)題要求去除最少的括號(hào)來(lái)得到給定字符串的合法的含有括號(hào)的字符串,要找到所有合法結(jié)果,還要保證去除最少的括號(hào),同時(shí)滿足這兩個(gè)條件。
      • 找出所有,通過(guò)隊(duì)列為空來(lái)保證。
      • 保證去除最少括號(hào)則是發(fā)現(xiàn)合法的字符串,就不要搜索了,直接跳出循環(huán),稱為剪枝。
  • 代碼
    • # -*-coding:utf-8-*-def is_valid(s):"""判斷是否括號(hào)合法:param s::return:"""count = 0for item in s:if item == "(":count += 1elif item == ")":count -= 1if count < 0:return Falsereturn count == 0def solve(s):res = []queue = []queue.append(s)while len(queue) > 0:# 每次去隊(duì)列找其中元素,這時(shí)隊(duì)列里面的都是一層的for item in queue:if is_valid(item):res.append(item)if len(res) > 0:# 只有這一層沒(méi)有合法的,才會(huì)繼續(xù)去除括號(hào)向下一層找return list(set(res))temp = []for item in queue:for i in range(len(item)):if item[i] == "(" or item[i] == ")":temp.append(item[:i] + item[i+1:])queue = list(set(temp))return list(set(res))if __name__ == '__main__':print(solve("(a)(b))()"))
  • 運(yùn)行結(jié)果
  • 補(bǔ)充說(shuō)明
    • 具體代碼可以查看我的Github,歡迎Star或者Fork
    • 參考書(shū)《你也能看得懂的Python算法書(shū)》

總結(jié)

以上是生活随笔為你收集整理的广度优先遍历算法-02合法的括号问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。