列印n對括號的全部有效組合
阿新 • • 發佈:2019-02-12
這道題最基本的思路是求出n對括號的全排列,然後對每種排列方式判定是否有效。判定方法如下:
但是括號只有左括號和右括號,排列組合時有大量重複的匹配排列,每生成一次排列都要排查是不是重複,效率較低。bool IsMatch(string& str) { if(str.size() % 2 != 0) return false; int result = 0; for(string::iterator it = str.begin(); it != str.end(); ++it) { if(*it == '(') ++result; else if(*it == ')') --result; else return false; if(result < 0) return false; } return result == 0; }
另一種思路是構造字串:假設當前插入一個字元,那麼有兩種選擇,插入左括號或者右括號,什麼時候可以安全的插入呢?
(1)左括號:插入左括號總是安全的,只有左括號沒有使用完,都可以插入左括號。
(2)右括號:插入右括號的時候需要注意,只有當已插入的右括號個數小於左括號的個數時,才可以插入右括號,否則永遠無法匹配。
因此函式需要分別記錄餘下的左括號和右括號數,插入左括號,下面步驟遞迴插入。或者,插入一個右括號,然後再遞迴插入,程式碼如下:
void AddParen(vector<string>& vec, int leftRem, int rightRem, string& str, int index) { if(leftRem == 0 && rightRem == 0) vec.push_back(str); else { if(leftRem > 0) { str[index] = '('; AddParen(vec, leftRem-1, rightRem, str, index+1); } if(rightRem > leftRem) { str[index] = ')'; AddParen(vec, leftRem, rightRem-1, str, index+1); } } } void GenerateParens(int count) { if(count < 1) return; vector<string> vec; string str(count*2, ' '); AddParen(vec, count, count, str, 0); for(vector<string>::iterator it = vec.begin(); it != vec.end(); ++it) cout << *it << " "; cout << endl; }