1. 程式人生 > >LeetCode--22. Generate Parentheses

LeetCode--22. Generate Parentheses

題目連結:https://leetcode.com/problems/generate-parentheses/submissions/

要求生成n組合法的括號序列,也就是2n個字元,每個字元取自'('或')',且這個字元序列是合法的Parenthesis(括號)。

思路一:最樸素的方法就是把所有的排列情況枚舉出來,說到排列的列舉當然小意思,可以參考這一篇https://blog.csdn.net/To_be_to_thought/article/details/85168167,當然本題列舉更簡單:就是在2n個位置上選擇'('或')',一共有2^(2n)種情況。

接下來就是要弄清楚怎樣判斷一個合法的括號序列這個問題,先來看LeetCode-20. Valid Parentheses這道題目,藉助棧的幫助可以幫助我們判斷括號字串的合法性,因為只有一種括號,這裡可以用棧來判斷,也可以用計數的方法:'('一定出現在開頭,最終'('和')'的數目一樣多的,並且在括號字串的第0位到某一位上累計的'('的數目大於或等於‘)’的數目。計數判斷的程式碼如下:

public static boolean isValid(String s)
    {
        int balance=0;
        for(int i=0;i<s.length();i++)
        {
            if(s.charAt(i)=='(')
                balance++;
            else
                balance--;
            if(balance<0)
                return false;
        }
        return balance==0?true:false;
    }

最終程式碼如下:

class Solution {
    
    public static LinkedList<String> ret;
    
    public static char[] record;
    
    public List<String> generateParenthesis(int n) {
        ret=new LinkedList<String>();
        record=new char[n*2];
        generateAll(0,n);
        return ret;
    }
    
    public static void generateAll(int idx,int n)
    {
        if(idx==2*n)
        {
            String tmp=new String(record);
            if(isValid(tmp))
                ret.add(tmp);
            return;
        }
        
        record[idx]='(';
        generateAll(idx+1,n);
        record[idx]=')';
        generateAll(idx+1,n);
    }
    
    
    public static boolean isValid(String s)
    {
        int balance=0;
        for(int i=0;i<s.length();i++)
        {
            if(s.charAt(i)=='(')
                balance++;
            else
                balance--;
            if(balance<0)
                return false;
        }
        return balance==0?true:false;
    }
}

思路二:怎樣生成字串之前就避免非法括號序列的生成呢?可以將左括號和右括號數量作為遞迴的引數傳遞實現實時檢查:

public class Solution{

    public static LinkedList<String> ret;
    public static char[] record;
    public static int left=0;
    public static int right=0;

    public static List<String> generateParenthesis(int n) {

        ret=new LinkedList<>();
        record=new char[2*n];
        backtrace(0,n);
        return ret;
    }

    public static void backtrace(int idx,int n)
    {
        if(idx==2*n)
        {
            ret.add(new String(record));
            return;
        }
        if(left<n)
        {
            record[idx]='(';
            left++;
            backtrace(idx+1,n);
            left--;
        }

        if(right<left && right<n)
        {
            record[idx]=')';
            right++;
            backtrace(idx+1,n);
            right--;
        }
    }
}

官方解答與上面程式碼相似:

class Solution {

    public static LinkedList<String> ret;
    
    public List<String> generateParenthesis(int n) {
        ret=new LinkedList<String>();
        backtrace("",0,0,n);
        return ret;
    }
    
    public static void backtrace(String s,int left,int right,int n)
    {
        if(s.length()==2*n)
        {
            ret.add(s);
            return;
        }
        if(left<n)
            backtrace(s+'(',left+1,right,n);
        
        if(right<left)
            backtrace(s+')',left,right+1,n);
    }
}