在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

詳解一道高頻算法題:括號生成

算法與數據結構 ? 來源:五分鐘學算法 ? 2020-06-03 17:19 ? 次閱讀

題目描述

給出 n 代表生成括號的對數,請你寫出一個函數,使其能夠生成所有可能的并且有效的括號組合。

例如,給出 n = 3,生成結果為:

[ "((()))", "(()())", "(())()", "()(())", "()()()" ] 題目解析

方法一:回溯算法(深度優先遍歷)

如果完成一件事情有很多種方法,并且每一種方法分成若干步驟,那多半就可以使用“回溯”算法完成。

“回溯”算法的基本思想是“嘗試搜索”,一條路如果走不通(不能得到想要的結果),就回到上一個“路口”,嘗試走另一條路。

因此,“回溯”算法的時間復雜度一般不低。如果能提前分析出,走這一條路并不能得到想要的結果,可以跳過這個分支,這一步操作叫“剪枝”。

做“回溯”算法問題的基本套路是:

1、使用題目中給出的示例,畫樹形結構圖,以便分析出遞歸結構;

一般來說,樹形圖不用畫完,就能夠分析出遞歸結構和解題思路。

2、分析一個結點可以產生枝葉的條件、遞歸到哪里終止、是否可以剪枝、符合題意的結果在什么地方出現(可能在葉子結點,也可能在中間的結點);

3、完成以上兩步以后,就要編寫代碼實現上述分析的過程,使用代碼在畫出的樹形結構上搜索符合題意的結果。

在樹形結構上搜索結果集,使用的方法是執行一次“深度優先遍歷”。在遍歷的過程中,可能需要使用“狀態變量”。

(“廣度優先遍歷”當然也是可以的,請參考方法二。)

我們以 n = 2 為例,畫樹形結構圖。

題解配圖(1)

畫圖以后,可以分析出的結論:

左右都有可以使用的括號數量,即嚴格大于 0 的時候,才產生分支;

左邊不受右邊的限制,它只受自己的約束;

右邊除了自己的限制以外,還收到左邊的限制,即:右邊剩余可以使用的括號數量一定得在嚴格大于左邊剩余的數量的時候,才可以“節外生枝”;

在左邊和右邊剩余的括號數都等于 0 的時候結算。

參考代碼如下:

publicclassSolution{ publicListgenerateParenthesis(intn){ Listres=newArrayList<>(); //特判 if(n==0){ returnres; } //執行深度優先遍歷,搜索可能的結果 dfs("",n,n,res); returnres; } /** *@paramcurStr當前遞歸得到的結果 *@paramleft左括號還有幾個沒有用掉 *@paramright右邊的括號還有幾個沒有用掉 *@paramres結果集 */ privatevoiddfs(StringcurStr,intleft,intright,Listres){ //因為是遞歸函數,所以先寫遞歸終止條件 if(left==0&&right==0){ res.add(curStr); return; } //因為每一次嘗試,都使用新的字符串變量,所以沒有顯式的回溯過程 //在遞歸終止的時候,直接把它添加到結果集即可,與「力扣」第46題、第39題區分 //如果左邊還有剩余,繼續遞歸下去 if(left>0){ //拼接上一個左括號,并且剩余的左括號個數減1 dfs(curStr+"(",left-1,right,res); } //什么時候可以用右邊?例如,((((((),此時 left < right, ????????//?不能用等號,因為只有先拼了左括號,才能拼上右括號 ????????if?(right?>0&&left

如果我們不用減法,使用加法,即 left 表示“左括號還有幾個沒有用掉”,right 表示“右括號還有幾個沒有用掉”,可以畫出另一棵遞歸樹。

題解配圖(2)

參考代碼如下:

publicclassSolution{ //方法 2:用加法 publicListgenerateParenthesis(intn){ Listres=newArrayList<>(); //特判 if(n==0){ returnres; } //這里的dfs是隱式回溯 dfs("",0,0,n,res); returnres; } /** *@paramcurStr當前遞歸得到的結果 *@paramleft左括號用了幾個 *@paramright右括號用了幾個 *@paramn左括號、右括號一共用幾個 *@paramres結果集 */ privatevoiddfs(StringcurStr,intleft,intright,intn,Listres){ //因為是遞歸函數,所以先寫遞歸終止條件 if(left==n&&right==n){ res.add(curStr); return; } //如果左括號還沒湊夠,繼續湊 if(left right, //不能用等號,因為只有先拼了左括號,才能拼上右括號 if(rightright){ //拼接上一個右括號,并且剩余的右括號個數減1 dfs(curStr+")",left,right+1,n,res); } } }

方法二:廣度優先遍歷

還是上面的題解配圖(1),使用廣度優先遍歷,結果集都在最后一層,即葉子結點處得到所有的結果集,編寫代碼如下。

publicclassSolution{ classNode{ /** *當前得到的字符串 */ privateStringres; /** *剩余左括號數量 */ privateintleft; /** *剩余右括號數量 */ privateintright; publicNode(Stringres,intleft,intright){ this.res=res; this.left=left; this.right=right; } @Override publicStringtoString(){ return"Node{"+ "res='"+res+'''+ ",left="+left+ ",right="+right+ '}'; } } publicListgenerateParenthesis(intn){ Listres=newArrayList<>(); if(n==0){ returnres; } Queuequeue=newLinkedList<>(); queue.offer(newNode("",n,n)); //總共需要拼湊的字符總數是2*n n=2*n; while(n>0){ intsize=queue.size(); for(inti=0;i0){ queue.offer(newNode(curNode.res+"(",curNode.left-1,curNode.right)); } if(curNode.right>0&&curNode.left

方法三:動態規劃

第 1 步:定義狀態 dp[i]

使用 i 對括號能夠生成的組合。

注意:每一個狀態都是列表的形式。

第 2 步:狀態轉移方程:

i 對括號的一個組合,在 i - 1 對括號的基礎上得到;

i 對括號的一個組合,一定以左括號 "(" 開始(不一定以 ")" 結尾),為此,我們可以枚舉右括號 ")" 的位置,得到所有的組合;

枚舉的方式就是枚舉左括號 "(" 和右括號 ")" 中間可能的合法的括號對數,而剩下的合法的括號對數在與第一個左括號 "(" 配對的右括號 ")" 的后面,這就用到了以前的狀態。

狀態轉移方程是:

dp[i] = "(" + dp[可能的括號對數] + ")" + dp[剩下的括號對數]

“可能的括號對數” 與 “剩下的括號對數” 之和得為 i,故“可能的括號對數” j 可以從 0 開始,最多不能超過 i, 即 i - 1;

“剩下的括號對數” + j = i - 1,故 “剩下的括號對數” = i - j - 1。

整理得:

dp[i] = "(" + dp[j] + ")" + dp[i- j - 1] , j = 0, 1, ..., i - 1

第 3 步:思考初始狀態和輸出:

初始狀態:因為我們需要 0 對括號這種狀態,因此狀態數組 dp 從 0 開始,0 個括號當然就是 [""]。
輸出:dp[n] 。
這個方法暫且就叫它動態規劃,這么用也是很神奇的,它有下面兩個特點:

1、自底向上:從小規模問題開始,逐漸得到大規模問題的解集;

2、無后效性:后面的結果的得到,不會影響到前面的結果。

publicclassSolution{ //把結果集保存在動態規劃的數組里 publicListgenerateParenthesis(intn){ if(n==0){ returnnewArrayList<>(); } //這里dp數組我們把它變成列表的樣子,方便調用而已 List>dp=newArrayList<>(n); Listdp0=newArrayList<>(); dp0.add(""); dp.add(dp0); for(inti=1;i<=?n;?i++)?{ ????????????Listcur=newArrayList<>(); for(intj=0;jstr1=dp.get(j); Liststr2=dp.get(i-1-j); for(Strings1:str1){ for(Strings2:str2){ //枚舉右括號的位置 cur.add("("+s1+")"+s2); } } } dp.add(cur); } returndp.get(n); } }

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4625

    瀏覽量

    93129
  • 遞歸
    +關注

    關注

    0

    文章

    29

    瀏覽量

    9042

原文標題:超詳細!詳解一道高頻算法題:括號生成

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    硬件工程師面試常考的一道,講講運算放大器的增益帶寬積

    Part 01 前言 想要學好運算放大器電路,個繞不過的參數就是增益帶寬積,只有理解了增益帶寬積,才能真正理解運算放大器電路的增益與帶寬的關系。什么是增益帶寬積呢?英文名字叫GBP或GBW
    的頭像 發表于 12-27 08:13 ?633次閱讀
    硬件工程師面試常考的<b class='flag-5'>一道</b><b class='flag-5'>題</b>,講講運算放大器的增益帶寬積

    ADS1256 8通依次采樣,數據不正確怎么解決?

    SPI總線速度1.40625MB/S,基于STM32的HAL庫下,對八通輸入同一道方波,方波頻率20HZ、40HZ、60HZ時,會出現只有部分通道采樣的數據能顯示波形,輸入其他頻率的方波時,會存在采樣到的數據顯示的波形占空比與輸入方波的占空比不相同,這種情況是屬于寄存器
    發表于 11-22 07:09

    AIGC算法解析及其發展趨勢

    AIGC(Artificial Intelligence Generated Content,人工智能生成內容)算法是當今前沿科技的代表,它利用人工智能技術和算法自動生成各種形式的內容
    的頭像 發表于 10-25 15:35 ?510次閱讀

    IPV6報文怎么進行通信

    寫這篇文章的啟發是在群里,看到個小兄弟說有嘗做一道IPV6的基礎,看到該消息想著自己也沒啥事,就做下,弄個飯錢也還行,然后就開始了。
    的頭像 發表于 10-25 09:36 ?290次閱讀
    IPV6報文怎么進行通信

    企業如何數字化轉型

    在當今這個日新月異的數字時代,企業的數字化轉型已不再是一道選擇,而是一道必答題。它不僅關乎企業的生存與發展,更是決定企業能否在激烈的市場競爭中脫穎而出的關鍵。 企業數字化轉型,簡而言之,就是利用
    的頭像 發表于 08-27 16:55 ?434次閱讀

    好未來與微軟開展合作,攜手構建智慧學習生態系統

    想象下,你正在解一道復雜的數學。這難度不小,你解題時遇到了瓶頸。這時,位“老師”出現在你面前,不是直接給出答案,而是像蘇格拉底式教學
    的頭像 發表于 08-20 10:12 ?558次閱讀

    工商業儲能選型指南及參數詳解

    行業普遍認為2023年是工商儲元年。如今,工商儲賽道仍然持續升溫中,無數新玩家涌入。但令人眼花繚亂的選型配置成為不少玩家的第一道門檻,今天小固就手把手帶你進行工商儲選型,為你進行核心參數詳解
    的頭像 發表于 08-05 14:52 ?3164次閱讀
    工商業儲能選型指南及參數<b class='flag-5'>詳解</b>

    Verilog testbench問題求助

    這是我在HDLbits網站上做到的一道,是testbench,請問這個代碼為什么input都是低電平0?我設置的時鐘就是周期10ns,占空比50%的時鐘信號啊?怎么會出現這種情況......
    發表于 07-21 11:14

    求助各位關于Verilog當中模塊例化、端口與引腳 的問題

    ? 4.assign a = b 當中的a和b都是信號?端口是不是不能寫在運算式當中? 5.同題組的題目當中還有一道這個: (1)這道題在寫的時候,就可以直接寫.in1(a),為什么?是因為in1是端口而a是信號
    發表于 07-15 20:38

    基于神經網絡的全息圖生成算法

    全息圖生成技術作為光學與計算機科學交叉領域的重要研究方向,近年來隨著神經網絡技術的飛速發展,取得了顯著進展。基于神經網絡的全息圖生成算法,以其強大的非線性擬合能力和高效的計算性能,為全息圖的生成
    的頭像 發表于 07-09 15:54 ?521次閱讀

    生成對抗網絡(GANs)的原理與應用案例

    生成對抗網絡(Generative Adversarial Networks,GANs)是種由蒙特利爾大學的Ian Goodfellow等人在2014年提出的深度學習算法。GANs通過構建兩個
    的頭像 發表于 07-09 11:34 ?1186次閱讀

    生成式AI的基本原理和應用領域

    生成式人工智能(Generative Artificial Intelligence,簡稱Generative AI)是種利用機器學習算法和深度學習技術,通過模擬人類的創造性思維過程,生成
    的頭像 發表于 07-04 11:50 ?1641次閱讀

    機器學習算法原理詳解

    機器學習作為人工智能的個重要分支,其目標是通過讓計算機自動從數據中學習并改進其性能,而無需進行明確的編程。本文將深入解讀幾種常見的機器學習算法原理,包括線性回歸、邏輯回歸、支持向量機(SVM)、決策樹和K近鄰(KNN)算法,探
    的頭像 發表于 07-02 11:25 ?1238次閱讀

    BLDC電機控制算法詳解

    算法。本文將詳細介紹BLDC電機的控制算法,包括電速算法、電流環控制算法、磁場導向控制算法等,并探討其原理、特點和應用。
    的頭像 發表于 06-14 10:49 ?1154次閱讀

    阿里云視頻生成技術創新!視頻生成使用了哪些AI技術和算法

    電子發燒友網報道(文/李彎彎)日前,阿里云宣布通義實驗室研發的視頻生成模型EMO正式上線通義App,免費對所有人開放。借助這功能,用戶可以在歌曲、熱梗、表情包中任選款模板,然后通過上傳
    的頭像 發表于 05-08 00:07 ?3415次閱讀
    主站蜘蛛池模板: 国产成人精品1024在线| 潘金莲国产三级视频在线| 天天夜干| 黄色片日本网站| 五月婷丁香| 色一情一乱一乱91av| 好男人社区在线观看www| 日本在线色视频| 在线天堂bt中文www在线| 久久影视免费体验区午夜啪啪| 欧美肥胖女人bbwbbw视频| 夜夜综合网| 成人性色生活影片| 精品卡1卡2卡三卡免费视频 | 日本超黄视频| 亚色在线| 国产精品虐乳在线播放| 免费看日本大片免费| 瑟瑟久久| 性在线视频| www.狠狠干| 男女交性视频免费视频| xxxxx日本69| 欧美大尺度aaa级毛片| 国产精品天天干| 韩国午夜精品理论片西瓜| 天天干天天操天天做| 性试验k8经典| 免费福利午夜影视网| 人人干日日操| 97精品伊人久久大香线蕉| 1024手机在线观看你懂的| 成人激情视频网| 国产午夜精品理论片免费观看| 人人艹人人射| 日本xxxxxxxxx69| 网站在线播放| 免费看h视频| 成人毛片一区二区三区| 一级毛片一片毛| 永久看日本大片免费|