實例
n = 3,所有的合法序列
((())) (()()) (())() ()(()) ()()()
思路
針對一個長度為2n的合法排列,第1到2n個位置都滿足如下規則
左括號的個數≥右括號的個數
所以,我們就可以按照這個規則去打印括號
假設在位置k我們還剩余left個左括號和right個右括號
- 如果left和right均為零,則說明我們已經完成一個合法排列,可以將其打印出來
- 如果left>0,打印左括號
- 如果right>0 並且 right>left 打印右括號
針對n=2,問題的解空間如下:
參考代碼
vector<string> generateParenthesis(int n) { vector<string> ans; generate(n, n, "", ans); return ans; } void generate(int leftNum, int rightNum, string s, vector<string> &result) { if(leftNum == 0 && rightNum == 0) { result.push_back(s); } if(leftNum > 0) { generate(leftNum-1, rightNum, s+'(', result); } if(rightNum > 0 && leftNum < rightNum) { generate(leftNum, rightNum-1, s+')', result); } }
擴展
該問題和《編程之美》的買票找零問題一樣:2n個人排隊買票,其中n個人持50元,n個人持100元。每張票50元,且一人只買一張票。初始時售票處沒有零錢找零。請問這2n個人一共有多少種排隊順序,不至於使售票處找不開錢?
可以把50塊錢看成(,100塊錢看成)。只有(始終大於等於)才可以找開錢。
結論
參考