1. 程式人生 > >Leetcode:Question22--Generate Parentheses

Leetcode:Question22--Generate Parentheses

題目描述

這裡寫圖片描述

解題思路

  1. 拿到這道題,首先思考的是哪些情況下括號匹配會出現錯誤。題目只列出了正確的括號匹配情況,因此需要自己觀察不匹配的情況。
  2. 首先可以注意到的是,左括號永遠是作為開頭出現,而右括號永遠是作為末尾出現。除了兩端之外,右括號的出現必須要求前面已經有左括號。因此一開始的想法是構建一個棧來儲存左括號,當往字串中寫入一個左括號時,向棧中push一個左括號,當棧中括號pop出來時,向字串中寫入一個右括號。因此就能夠保證,右括號和左括號匹配。
  3. 另外就是如何遍歷所有情況的問題。除了頭和尾,假如左括號的數沒有達到上界,那麼既可以加左括號也可以加右括號。假如左括號數量已滿,那麼就只能新增右括號。由於每種情況都是建立在前面情況的基礎上,所以用遞迴比較合適
  4. 最後就是設定一個值來儲存所有字串,因此聲明瞭一個private的物件。
  5. 做到這裡發現,其實棧的作用只是用來記錄左右括號的數目,因此完全可以設定一個變數來記錄而不需要維護一個棧。因此在增加左右括號時只需要滿足以下兩種情況
    • 已存在的左括號數大於右括號數
    • 左括號數小於要求的數目
    • 以左括號開頭,右括號結尾

程式碼分析

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        string s = "";
        addBracket(0, 0, n, s);
        return
result; } void addBracket(int left, int right, int max, string s) { if (s.size() == max * 2) { result.push_back(s); return; } else { if (left < max) { addBracket(left + 1, right, max, s + '('); } if
(right < left) { addBracket(left, right + 1, max, s + ')'); } } } private: vector<string> result; };

此題採用了C++ 語言,通過使用遞迴完成。在遞迴過程的程式碼編寫中出現了一點錯誤。一開始寫的是

    /-----/
        else {
            if (left < max) {
                addBracket(++left, right, max, s + '(');   
            }
            if (right < left) {
                addBracket(left, ++right, max, s + ')');
            }
        }

    /----/

結果出現錯誤。debug發現,當遞迴到字串為“ (() ” 時,左括號數量顯示為3,可見,在從上一步” ((())) ” 遞迴過程返回到這一步時,左括號數先進行了一次遞增。

接下來我又嘗試了一下 將自增放在右邊(顯然已經知道是錯的),發現什麼都沒有輸出。debug發現,在遞迴進入下一層函式時,是先進入函式在進行加1,因此left和right的值一直是0。

可見,在遞迴時,不能改變所在層的變數的值。