class Solution { public: vector<string> ans; void helper(string& cur, int left, int right, int n) { //首先兩者都必須小於等於n // not a must //這一行剪枝不是必須的,因爲按照我們增長的規律,是不會出現非法字符串的。 //if(left > n || right > n || left < right) // return; if(left == n && right == n) //左右相等,到終點了 ans數組在這裏等你 { ans.push_back(cur); return; } // 如果左側比n小,可以添加左側,也可以添加右側 if(left < n) { cur.push_back('('); helper(cur, left+1, right, n); cur.pop_back();
if(right < left) { cur.push_back(')'); helper(cur,left, right+1,n); cur.pop_back(); } } else // left == n { cur.push_back(')'); helper(cur, left ,right+1, n); cur.pop_back(); } } vector<string> generateParenthesis(int n) { string tmp; helper(tmp,0,0,n); return ans; } };
首先這是一個遞歸,回溯,在最深的地方判斷,滿足條件的話,就存儲起來。
另外,一個容易忽略的點就是,爲什麼cur.push_back以後要pop_back?
因爲是遞歸調用,你調用之後,不知道被修改成啥樣了。如果每一個深度的函數,都能保證,自己這一層調用完之後,完璧歸趙,那麼...
需要再研究,這一塊還有盲點。