• 括号生成


    原题点这里

    方法1:

    通过dfs,穷举所有的可能,然后判断每一种可能,是否合法。

    public static List<String> generateParenthesis(int n) {
            List<String> ans = new ArrayList<>();
            char[] par = new char[2*n];
            getAll(par,0,2*n,ans);
            return ans;
        }
        public static void getAll(char[] par,int pos,int len,List<String> ans){
            if(pos==len){
                if(vaild(par)){
                    ans.add(new String(par));
                }
                return;
            }
            par[pos]='(';
            getAll(par,pos+1,len,ans);
            par[pos]=')';
            getAll(par,pos+1,len,ans);
        }
        public static boolean vaild(char[] par){
            int count =0;
            for(int i=0;i<par.length;i++){
                if(count<0) break;
                if(par[i]=='(') count++;
                if(par[i]==')') count--;
            }
            if(count==0) return true;
            return false;
        }
    View Code

    方法2:

    我们在dfs的时候,可以改变策略。我们记录左括号个个数和右括号的个数。然后只有当左括号个数<n时,我们添加一个左括号。当右括号个数<左括号时,我们添加右括号。这样我们就只生成了合理的结果。

    public static List<String> generateParenthesis(int n) {
            List<String> ans = new ArrayList<>();
            StringBuilder par = new StringBuilder();
            getAll(par,0,0,n,ans);
            return ans;
        }
        public static void getAll(StringBuilder par,int left,int right,int len,List<String> ans){
            if(par.length()==2*len){
                ans.add(par.toString());
                return;
            }
            if(left<len){
                par.append('(');
                getAll(par,left+1,right,len,ans);
                par.deleteCharAt(par.length()-1);
            }
            if(right<left){
                par.append(')');
                getAll(par,left,right+1,len,ans);
                par.deleteCharAt(par.length()-1);
            }
        }
    View Code

    我们重点来看一下这个dfs,这里涉及到回溯:

        public static void getAll(StringBuilder par,int left,int right,int len,List<String> ans){
            if(par.length()==2*len){
                ans.add(par.toString());
                return;
            }
            if(left<len){     ----------------------> a
                par.append('(');   
                getAll(par,left+1,right,len,ans);
                par.deleteCharAt(par.length()-1);  ------------------->c
            }
            if(right<left){   ----------------------->b
                par.append(')');
                getAll(par,left,right+1,len,ans);
                par.deleteCharAt(par.length()-1);
            }
        }

    最上面几层:a (

          a( a(

          a( a( a( ,然后

          a( a( a( b) b) b)  ,执行到6层深度之后, 碰到第一个return。  ((()))

          然后就一直回溯:

          a( a( a( c  ------->   a( a( c[删掉一个左括号] b) a(  b) b)   第二个return  (()())

          然后继续回溯  ,神奇。

  • 相关阅读:
    vi错误terminal too wide解决方法
    怎么重启shell ubuntu
    程序异常退出 却没有产生core文件
    Linux执行shell脚本方式及区别&命令后台运行
    Linux C程序异常退出怎么办——core文件帮你忙
    Linux中生成Core Dump系统异常信息记录文件的教程
    Linux环境下段错误的产生原因及调试方法小结
    Linux core dump file详解
    putty工具常见设置
    Download PuTTY: latest development snapshot
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/12669519.html
Copyright © 2020-2023  润新知