一、问题导出

今天在做算法题目的时候遇到了一道左右括号匹配的问题,问题如下:

打印n对括号的全部有效组合(左右括号正确匹配)Java实现-LMLPHP

二、问题思考

(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;
         }
    }

}

运行结果:

打印n对括号的全部有效组合(左右括号正确匹配)Java实现-LMLPHP

四、总结

虽然这题不算很难,但做题的思想还是很经典的,由小及大,所以还是记了下来巩固一下,还有就是在正常逻辑中用set时,不小心将

Set<String> newset=new HashSet<String>();这一行放到了双重循环之外,导致出现java.util.ConcurrentModificationException的异常,

因为之前看过书知道这种异常,但是自己打代码的时候还没有遇到过,既然遇到了,就要记录一下,免得下次再犯。

05-26 07:13