LeetCode-022-括號生成

雄獅虎豹發表於2021-10-19

括號生成

題目描述:數字 n 代表生成括號的對數,請你設計一個函式,用於能夠生成所有可能的並且 有效的 括號組合。

示例說明請見LeetCode官網。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解法一:窮舉法
通過遞迴的方式獲取所有可能的組合,然後判斷每一種組合是否是有效的括號組合,如果是,新增到結果集中,最後返回符合的結果集合。
解法二:回溯法
也是通過遞迴的方式,但是可以根據已經出現過的左右括號的個數來判斷下一個字元可以是左括號還是右括號,這樣最後遞迴得到的都是有效的括號組合,效率較高。
import java.util.ArrayList;
import java.util.List;

public class LeetCode_022 {
    /**
     * 暴力破解法
     *
     * @param n
     * @return
     */
    public static List<String> generateParenthesis(int n) {
        List<String> result = new ArrayList<>();
        generateAllPossibleResults(new char[2 * n], 0, result);
        return result;
    }

    /**
     * 遞迴方法:2*n 的字元陣列,每一個字元都有2種可能,直到字元陣列被填滿,校驗是否符合
     *
     * @param current
     * @param pos
     * @param result
     */
    public static void generateAllPossibleResults(char[] current, int pos, List<String> result) {
        if (pos == current.length) {
            // 當字元陣列被填充滿時,校驗是否符合
            if (valid(current)) {
                result.add(new String(current));
            }
        } else {
            // 遞迴
            current[pos] = '(';
            generateAllPossibleResults(current, pos + 1, result);
            current[pos] = ')';
            generateAllPossibleResults(current, pos + 1, result);
        }
    }

    /**
     * 判斷是否符合條件
     *
     * @param current
     * @return
     */
    public static boolean valid(char[] current) {
        int balance = 0;
        for (char c : current) {
            if (c == '(') {
                ++balance;
            } else {
                --balance;
            }
            if (balance < 0) {
                return false;
            }
        }
        return balance == 0;
    }

    static List<String> res = new ArrayList<>();

    /**
     * 方法二:回溯法
     *
     * @param n
     * @return
     */
    public static List<String> generateParenthesis2(int n) {
        if (n <= 0) {
            return res;
        }
        getParenthesis("", n, n);
        return res;
    }

    private static void getParenthesis(String str, int left, int right) {
        if (left == 0 && right == 0) {
            res.add(str);
            return;
        }
        if (left == right) {
            //剩餘左右括號數相等,下一個只能用左括號
            getParenthesis(str + "(", left - 1, right);
        } else if (left < right) {
            //剩餘左括號小於右括號,下一個可以用左括號也可以用右括號
            if (left > 0) {
                getParenthesis(str + "(", left - 1, right);
            }
            getParenthesis(str + ")", left, right - 1);
        }
    }

    public static void main(String[] args) {
        System.out.println("=====暴力破解法=====");
        List<String> strings = generateParenthesis(4);
        for (String string : strings) {
            System.out.println(string);
        }

        System.out.println("=====回溯法=====");
        List<String> strings1 = generateParenthesis2(4);
        for (String s : strings1) {
            System.out.println(s);
        }
    }
}
【每日寄語】 一萬個美麗的未來,抵不上一個溫暖的現在。

相關文章