給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。
例如,給出 n = 3,生成結果為:
[「((()))」,
「(()())」,
「(())()」,
「()(())」,
「()()()」
]當初的想法:
生成n個括號的排列組合,可以在生成n-1個括號的基礎上進行處理,將括號分別加在其上一步實現的左面,右面,兩邊。
但是這會漏掉一些情況:當n=4時,「(())(())」這種情況會漏掉。
改進當初的想法:
生成n個括號的組合,依然是基於前面的結果進行處理,當初的想法只用到了第n-1步的值,導致結果會漏掉一些情況。這次不僅僅用到第n-1步的值,還會用到其他的結果,那就需要在求解的過程中將所有的結果儲存。
其實本質思想是:動態規劃
class
solution
}else
q=i-
1-p;
for(
int k=
0;k.size()
;++k)}}
} cell.
push_back
(c);
}return cell[n];}
};
比較精煉的寫法
這裡cell在n=0時,存入的是乙個空串,大大方便了處理過程
class
solution);
//第0行
cell.
push_back()
;//第一行
for(
int i=
2;i<=n;
++i)}}
cell.
push_back
(c);
}return cell[n];}
};
特別注意:下面這種寫法就不適合先存到乙個vector的變數c中,再將c push_back到cell中,因為cell預先分配了空間。
class
solution
; cell[1]
=;for(
int i=
2;i<=n;
++i)}}
}return cell[n];}
};
基本思想:回溯思想
參考:回溯
構建深度優先樹:
class
solution
private
:void
fun(
int left,
int right,vector
&res,string &c)
else
if(rightif(left>0)
if(right>
0&&right>=left)}}
;
說明:
上述剪枝的條件判斷提高了**的執行效率,如果沒有剪枝,**執行起來時間會用的更長。
上述回溯使用的是減法的形式,左右括號還剩幾個可以用;同樣,也可以使用加法的形式,左右括號使用了幾個,**邏輯完全一樣,只不過中間判斷的條件有變化。 二刷
回溯
class
solution
private
:void
dfs(unordered_set
& res, string temp,
int l,
int r,
int n)
dfs(res, temp +
'(', l +
1, r, n)
;dfs
(res, temp +
')', l, r +
1, n);}
};
回溯**模板:
void
(變數,&結果變數)
bfs:
廣度優先遍歷
struct node};
class
solution
if(t.l +
1<= n)
if(t.r +
1<= n && t.r +
1<= t.l)
}return res;}}
;
動態規劃:
class
solution
; res[1]
=;for(
int i =
2; i <= n;
++i)}}
}return res[n];}
};
LeetCode22 括號生成
題幹 給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。例如,給出 n 3,生成結果為 演算法思想 先看括號匹配,既然要達到括號匹配,就一定要滿足stack的操作 不多說 則組合數的結果則是卡特蘭數。要輸出正確組合數,可採用遞迴,用兩個變數l,r分別表示剩餘左...
leetcode 22 括號生成
給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。例如,給出 n 3,生成結果為 要把這個當成下棋,左括號為黑,右括號為白,則轉換為 3黑3白有幾種排列方式 每一步都有兩個選擇 下黑或者下白,但是場上下白子時剩下的黑子必須比剩下的白子多 比n 2時,有黑白黑白...
leetcode 22 括號生成
給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。例如,給出 n 3,生成結果為 參考官方題解 方法二 回溯法 只有在序列仍然保持有效才會新增 如果還有位置,我們可以開始放乙個左括號。如果不超過右括號數量不超過左括號的數量可以放乙個右括號。class solu...