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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

有效括号生成

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 有效括号生成 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有效括號生成

      • 題目描述
      • 題目分析
        • 深度搜索法
          • python代碼
        • 動態規劃法
          • python代碼

??合法的括號匹配的問題之前已經講解過了,現在再看一個括號生成的題目。

題目描述

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

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

[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]

題目分析

??既然之前已經分析過合法的括號判斷,那么只要把n個左括號和n個右括號全排列,然后對排列的結果去做一個有效驗證,好了,這個問題解決了。但是仔細一分析,判斷一個括號是否有效,復雜度O(n)O(n)O(n),生成2n個括號字符的全排列,時間復雜度O(22n)O(2^{2n})O(22n),這很難辦啊。所以全排列的方式行不通。

深度搜索法

??全排列里面有很多左括號和右括號數目不等的,可以直接排除了,所以浪費了很多判斷。我們可以通過回溯提前把不合理的字符排除掉。但是回溯法只能是逐漸的字符串變長,也就是深度優先搜索的原理。但是我們這個時候在每一次增加括號的時候,我們保證右括號不會超過當前的左括號數目即可。還要保證最終的括號數目,左括號和右括號的數目都是n。
??根據這個思想,我們可以去寫代碼了,我們記錄下當前左括號的數目,記錄下當前右括號的數目,如果左括號大于右括號,且左括號數目小于n,此時我們深度搜索的路徑包括兩條,添加左括號和右括號。如果左括號數目等于n了,那么就只有一條路徑,如果左括號數目等于右括號數目了且不等于n,此時只能添加左括號。如果兩者數目相等,且等于n,則可以返回了,已經生成了一組合法的括號字符。整個算法就是一個深度遍歷,可以采用遞歸來實現。

python代碼
class Solution:def generateParenthesis(self,n):ans=[]self.max=nself.backtrack(ans, "", 0, 0)return ansdef backtrack(self, ans, cur, left, right):if left==self.max:ans.append(cur +')' * (self.max - right))returnif(left<self.max):self.backtrack(ans, cur +'(', left + 1, right)if right<left:self.backtrack(ans, cur +')', left, right + 1)

??可以看到,這種方式保證了左括號的數目始終多于右括號,這樣生成出來的一定是合法的括號字符串。因為每次生成保證了都是合法的前綴,這個復雜度就大大的減少了。
??事實上,合法的括號數目,我們在卡特蘭數的應用分析了n個括號的合法種類數就是卡特蘭數列的第n項,我們大致可以根據卡特蘭數的性質,分析問題的規模。我們知道卡特蘭數的漸進上界是O(4nn)O\left ( \frac{4^n}{ \sqrt{n}} \right )O(n?4n?),而每一個合法的序列,我們是通過O(n)O(n)O(n)次添加字符生成出來的。

動態規劃法

??既然這個問題和卡特蘭數相關,那么一定可以根據卡特蘭數的特點,一定可以把這個問題轉換成以前所有狀態的窮舉。說的通俗一點就是,如果我們研究問題規模為n,那么問題規模之和為n-1的兩兩組合一定可以用得上,如果這句話理解不了可以直接跳到下一段。
??我們為了降低問題規模,可以考慮在問題規模為n-1的情況上加一對括號,可是這個多出來的一對括號應該往哪加。顯然,我們可以把這個括號加在所有的合法匹配的括號之后。如果合法匹配數為0的時候,我們就把括號加在了最前面,就是()+dpn?1()+dp_{n-1}()+dpn?1?,再者我們可以把括號加到一對合法括號后面,也是(dp1)+dpn?2(dp_1)+dp_{n-2}(dp1?)+dpn?2?依次類推,n-1個合法的括號總共可以分解出n-1種情況。每個情況分為兩部分,前面一部分是dp_i,后面一部分是dp_n-1-i,其實也就是兩部分滿足下標之和為n-1就行。
??據此我們可以寫出動態規劃的遞歸式。dpi="("+dpj+")"+dpi?j?1,wherej<idp_i="(" + dp_j + ")"+dp_{i-j-1}, \ where \ j<idpi?="("+dpj?+")"+dpi?j?1?,?where?j<i。事實上,幾乎所有的卡特蘭數問題都可以寫成類似的遞推式,對所有兩兩組合為n-1的情況然后窮舉,并做出一定的修改。大家可以記住這個結論,當然也可以寫成數學表達式,我直接寫成程序的表達式即可。下面就可以根據這個表達式寫代碼。只需要對dpjdp_jdpj?dpi?j?1dp_{i-j-1}dpi?j?1?做個全排列即可。

python代碼
class Solution:# 動態規劃def generateParenthesis(self, n: int) -> List[str]:dp=[[] for i in range(n+1)]dp[0]=['']for i in range(1,n+1):for j in range(i):dp[i].extend(self.compent(dp[j],dp[i-j-1]))return dp[n]def compent(self, l, r):# 全排列代碼,當時只寫了一行,為了大家好理解,特此重寫一份res=[]for s1 in l:for s2 in r:res.append('('+s1+')'+s2 )return res

??分析時間復雜度的時候大家需要注意一下,就是雖然這個代碼寫出來是4個for,但是這個代碼的時間復雜度不是O(n4)O(n^4)O(n4),相比于上面的回溯法,其實時間復雜度的指數部分還是保持的,單是求問題規模等于n的情況,時間復雜度就已經達到了O(4nn)O\left ( \frac{4^n}{ \sqrt{n}} \right )O(n?4n?)

總結

以上是生活随笔為你收集整理的有效括号生成的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。