LeetCode - 22. 括號生成
小知識,大挑戰!本文正在參與“程式設計師必備小知識”創作活動。
原題:22. 括號生成
題目大意:給定一個 n,生成 n 對括號的有效排列,例如給定的 n 是 3,則有效的排列是:["((()))","(()())","(())()","()(())","()()()"]
。
通常這樣的排列組合題目可以使用遞迴和深度優先遍歷來完成,先把遞迴的架子寫出來:
``` java void dfs() { // 遞迴的終止條件,也就是在什麼情況下不在進行遞迴呼叫
// 處理當前層的邏輯
// 進行下一層的遞迴呼叫
// 如果需要的話,再恢復遞迴呼叫錢的狀態
} ```
然後,我們需要兩個變數:
- 一個列表來儲存結果集
- 一個 StringBuffer 用來拼接每一個可能結果
``` java
class Solution {
List
private void dfs() {
// 遞迴的終止條件,也就是在什麼情況下不在進行遞迴呼叫
// 處理當前層的邏輯
// 進行下一層的遞迴呼叫
// 如果需要的話,再恢復遞迴呼叫錢的狀態
}
} ```
接下來,處理 dfs
方法中的邏輯就可以了。這裡的關鍵是如何生成有效的括號排列,需要滿足以下條件:
- 如果已經排列的左括號的數量小於 n,則可以追加左括號,也就是,只要左括號沒用完,任何時候都可以追加
- 如果已經排列的右括號比做擴好少,就可以追加右括號,也就是成對的一組括號,左括號要比右括號線出現。
滿足以上兩個條件就可以了。
最終程式碼:
``` java
class Solution {
List
private void dfs(int l, int r, int n) {
// 遞迴的終止條件,也就是在什麼情況下不在進行遞迴呼叫
// 當結果的長度是括號數量的兩倍時,就結束遞迴
if (sb.length() == n * 2) {
result.add(sb.toString());
return;
}
// 追加半括號時,滿足上述的任意條件,都可以追加對應的半括號
// 完成遞迴呼叫之後,要把之前追加的半括號刪除
if (l < n) {
// 處理當前層的邏輯
sb.append('(');
// 進行下一層的遞迴呼叫
dfs(l + 1, r, n);
// 如果需要的話,再恢復遞迴呼叫錢的狀態
sb.deleteCharAt(sb.length() - 1);
}
if (r < l) {
// 處理當前層的邏輯
sb.append(')');
// 進行下一層的遞迴呼叫
dfs(l, r + 1, n);
// 如果需要的話,再恢復遞迴呼叫錢的狀態
sb.deleteCharAt(sb.length() - 1);
}
}
} ```
「其他文章」
- Spring 原始碼閱讀 42:AutowiredAnnotationBeanPostProcessor 分析(3)
- Spring 原始碼閱讀 41:AutowiredAnnotationBeanPostProcessor 分析(2)
- Kafka 消費者組 Rebalance 詳細過程
- Spring 原始碼閱讀 01:Resource 資源抽象
- 初識機器學習:迴歸分析
- 初識機器學習:Louvain 社群發現演算法
- 初識機器學習:關聯規則
- 使用 Redis 實現分散式鎖的方法
- Kafka 目錄裡的指令碼那麼多,它們都是用來幹什麼的?
- Kafka 消費者組位移重設的幾種方式
- LeetCode - 84. 柱狀圖中最大的矩形
- LeetCode - 22. 括號生成