第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.5 “逐步生成結果”之非數值型問題 (合法括號)
題目一:
輸入括號對數,輸出所有的合法組合,比如輸入1,輸出"()",輸入3,輸出"()()(), (()()), ()(()), (())(), ((()))"。
思路:比如輸入1,輸出"()",那麼輸入2的話,我們就可以在輸入1的基礎上往左插入一對括號,往右插入一對括號以及把它用括號包含起來。這樣的話左邊和右邊是相同的,我們可以用set集合來去除重複。畫個示意圖如下:
程式碼:
import java.util.HashSet;
import java.util.Set;
public class 合法括號 {
public static void main(String[] args) {
Set<String> parenthesis = parenthesis(3);
System.out.println(parenthesis);
System.out.println("==============================");
parenthesis = parenthesis1(3);
System.out.println(parenthesis);
}
/* 逐步生成之遞迴解法 */
public static Set<String> parenthesis(int n) {
Set<String> s_n = new HashSet<>();
if (n == 1) {
s_n.add("()");
return s_n;
}
Set<String> s_n_1 = parenthesis(n - 1);
for (String eOfN_1 : s_n_1) {
s_n.add("()" + eOfN_1);
s_n.add(eOfN_1 + "()");
s_n.add("(" + eOfN_1 + ")");
}
return s_n;
}
/* 迭代形式 */
public static Set<String> parenthesis1(int n) {
Set<String> res = new HashSet<>(); // 儲存上次迭代的狀態
res.add("()");
if (n == 1) {
return res;
}
for (int i = 2; i <= n; i++) {
Set<String> res_new = new HashSet<>();
for (String e : res) {
res_new.add(e + "()");
res_new.add("()" + e);
res_new.add("(" + e + ")");
}
res = res_new;
}
return res;
}
}
結果:
注意:這兒的遞迴思路有誤,會漏算。當n=4時,"(())(())"這種情況就列印不出來,不過上面的程式碼也算是給我們提供了一種遞迴的思路。下面寫出正確的遞迴思路:
解題思路:括號對的合法序列,已經插入的左括號的數目大於等於右括號的數目。
(1)插入左括號:剩餘的括號中,還有左括號;
(2)插入右括號:剩餘的括號中,右括號的數目大於左括號的數目;
程式碼及其結果:
public class 合法括號_1 {
public static void printPar(int l, int r, char[] str, int count) {
if (l < 0 || r < l)
return;
if (l == 0 && r == 0) {
System.out.println(str);
} else {
if (l > 0) {
str[count] = '(';
printPar(l - 1, r, str, count + 1);
}
if (r > l) {
str[count] = ')';
printPar(l, r - 1, str, count + 1);
}
}
}
public static void main(String[] args) {
int count = 4;
char str[] = new char[count * 2];
printPar(count, count, str, 0);
}
}
//結果
/*
(((())))
((()()))
((())())
((()))()
(()(()))
(()()())
(()())()
(())(())
(())()()
()((()))
()(()())
()(())()
()()(())
()()()()
*/
題目二:
判斷一個括號字串是否合法。
思路:直接看程式碼即可,很容易懂,這裡要注意一下中文括號和英文括號是不同的。
程式碼:
public class Test {
public static void main(String[] args) {
System.out.println(chkParenthsis("()a()", 5));
System.out.println(chkParenthsis("()()", 4));
System.out.println(chkParenthsis(")())", 4));
System.out.println(chkParenthsis("(())", 4));
System.out.println("測試中文括號:"+chkParenthsis("()()", 4));
}
/**
* 檢查括號字串是否合法
* @param A 源串
* @param n 源串長度
* @return
*/
public static boolean chkParenthsis(String A,int n){
if(n%2!=0){
return false;
}
int count = 0;
for (int i = 0; i < A.length(); i++) {
if (A.charAt(i) == '('||A.charAt(i) == '(') { // 避免中文括號
count++;
} else if (A.charAt(i) == ')'||A.charAt(i) == ')') {
count--;
} else
return false;
if (count < 0)
return false;
}
return true;
}
}
結果:
相關文章
- 第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.4 硬幣表示某個給定數值遞迴
- 第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.3 題解:機器人走方格問題遞迴機器人
- 數獨問題(DFS+回溯)
- leetcode:遞迴:括號生成LeetCode遞迴
- 資料結構括號匹配問題資料結構
- 遞迴問題遞迴
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- 回溯和遞迴實現迷宮問題(C語言)遞迴C語言
- c++迷宮問題回溯法遞迴演算法C++遞迴演算法
- LeetCode - 22. 括號的生成(遞迴)1LeetCode遞迴
- 資料結構和演算法——遞迴-八皇后問題(回溯演算法)資料結構演算法遞迴
- 回溯問題
- 最長有效括號的問題
- LeetCode 3: PairsOfParentheses (括號匹配問題)LeetCodeAI
- 遞迴路徑問題遞迴
- 遞迴-*全排列問題遞迴
- n皇后問題--回溯法,以DFS的方式搜尋
- 回溯問題Python框架總結——排列組合問題Python框架
- leetcode題解(遞迴和回溯法)LeetCode遞迴
- 請教一個切片遞迴賦值的問題遞迴賦值
- 樹遞迴問題的求解遞迴
- hdu2048遞迴問題遞迴
- hdu2049遞迴問題遞迴
- 括號匹配的檢驗問題(C++)C++
- 迴文數問題
- 遞迴求解漢諾塔問題遞迴
- 遞迴解決全排列問題遞迴
- 遞迴——深度優先搜尋(DFS)——以滑雪問題為例(自頂而下)遞迴
- 洛谷題單指南-數學基礎問題-P2651 新增括號III
- Acwing166 數獨題解 - DFS剪枝最佳化
- 回溯法解決全排列問題總結
- 遞迴中的遞推與迴歸以及返回值和函式儲存的問題(以階乘問題進行討論)遞迴函式
- C#資料結構與演算法系列(十四):遞迴——八皇后問題(回溯演算法)C#資料結構演算法遞迴
- 解決 Python 指令碼無法生成結果的問題Python指令碼
- 力扣刷題Python筆記:括號生成力扣Python筆記
- 數倉sql場景:迭代求結果問題SQL
- 【機器學習】--迴歸問題的數值優化機器學習優化
- 回溯法求迷宮問題