/**
* 功能:打印n對括號的所有有效組合(即左右括號正確配對)。java
*/app
兩種方法:ide
方法一:spa
[java] view plain copy.net
- /**
- * 思路:在括號的最前面或者原有的每對括號裏面插入一對括號。至於其餘任意位置,好比字符串的末尾,都會跟以前的狀況重複。
- * 注意:將字符串放進結果列表以前,必須檢查列表有無重複。
- * @param remaining
- * @return
- */
- public static HashSet<String> generateParens(int remaining){
- HashSet<String> set=new HashSet<String>();
-
- if(remaining==0)
- set.add("");
- else{
- HashSet<String> prev=generateParens(remaining-1);
- for(String str:prev){
- //括號內插入
- for(int i=0;i<str.length();i++){
- if(str.charAt(i)=='('){
- String s=insertInside(str,i);
- set.add(s);//插入元素以前,HashSet會自動檢查有無重複
- }
- }
- //括號最前面插入
- if(!set.contains("()"+str))
- set.add("()"+str);
- }
- }
- return set;
- }
-
- /**
- * 在每對括號內插入
- * @param str
- * @param leftIndex
- * @return
- */
- public static String insertInside(String str,int leftIndex){
- String left=str.substring(0,leftIndex+1);//左括號以後插入括號,因此須要leftIndex+1
- String right=str.substring(leftIndex+1);
- return left+"()"+right;
- }
方法二:blog
[java] view plain copy遞歸
- /**
- * 思路:從頭開始構造字符串,避免出現重複字符串。注意加入左括號和右括號,只要字符串仍然有效。
- * 每次遞歸調用,都有一個索引指向字符串的某個字符。選擇左括號和右括號:
- * 1)左括號:只要左括號尚未用完,就能夠插入左括號。
- * 2)右括號:只要不形成語法錯誤,就能夠插入右括號(右括號比左括號多,即語法錯誤)。
- * 所以,只需記錄容許插入的左右括號數目。若是還有左括號可用,就插入一個左括號,而後遞歸。
- * 若是後括號比左括號多,(即便用中的左括號比右括號多),就插入一個右括號,而後遞歸。
- *
- * 在字符串的每個索引對應位置插入左括號和右括號,並且絕對不會重複索引!!!
- * @param count
- * @return
- */
- public static ArrayList<String> generateParens2(int count){
- ArrayList<String> list=new ArrayList<String>();
- char[] str=new char[count*2];
- addParens(list,count,count,str,0);
-
- return list;
- }
-
- public static void addParens(ArrayList<String> list, int leftRem, int rightRem, char[] str, int count) {
- // TODO Auto-generated method stub
- if(leftRem<0||rightRem<leftRem)
- return;
-
- if(leftRem==0&&rightRem==0){
- String s=String.copyValueOf(str);
- list.add(s);
- }
-
- if(leftRem>0){
- str[count]='(';
- addParens(list, leftRem-1, rightRem, str, count+1);
- }
-
- if(rightRem>leftRem){
- str[count]=')';
- addParens(list, leftRem, rightRem-1, str, count+1);
-
- }
- }