一、問題導出
今天在做算法題目的時候遇到了一道左右括號匹配的問題,問題如下:
二、問題思考
(1)這種要列出全部可能性的題目很容易想到由小到大去發現規律,用遞歸或者暴力搜索。
首先1的情況,一個括號只有一種可能,就是()
接着想2的情況,加個括號,可以在1的基礎上加在其左邊、右邊或者包圍住1,即()()、()()、(())去掉重復就剩下兩種
同理3在2的基礎上,都加上左邊、右邊、包住的括號
(2)用何種數據結構去存儲括號呢?首先括號是字符串,再想到要去掉重復,所以想到用Hashset存儲
三、代碼實現
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
//遞歸
/*
Set<String> set=dp(n);
for (String string : set) {
System.out.println(string);
}*/
//正常邏輯
Set<String> set=getBracket(n);
for (String string : set) {
System.out.println(string);
}
}
private static Set<String> getBracket(int n) {
Set<String> set=new HashSet<String>();
set.add("()");
if(n==1){
return set;
}else{
for(int i=1;i<n;i++){
Set<String> newset=new HashSet<String>();
for (String string : set) {
newset.add("()"+string);
newset.add(string+"()");
newset.add("("+string+")");
}
set=newset;
}
return set;
}
}
//遞歸
public static Set<String> dp(int n){
Set<String> set=new HashSet<String>();
if(n==1){
set.add("()");
return set;
}else{
Set<String> set2=dp(n-1);
for (String string : set2) {
//左邊加
set.add("()"+string);
//右邊加
set.add(string+"()");
//包圍住
set.add("("+string+")");
}
return set;
}
}
}
運行結果:
四、總結
雖然這題不算很難,但做題的思想還是很經典的,由小及大,所以還是記了下來鞏固一下,還有就是在正常邏輯中用set時,不小心將
Set<String> newset=new HashSet<String>();這一行放到了雙重循環之外,導致出現java.util.ConcurrentModificationException的異常,
因為之前看過書知道這種異常,但是自己打代碼的時候還沒有遇到過,既然遇到了,就要記錄一下,免得下次再犯。