括号生成

208 阅读1分钟

题目

回溯

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {

        Main main = new Main();
        int [] nums = new int[] {-1, 2, 1, -4};
        main.generateParenthesis(3);
    }

    int n = 0;
    List<String> ans = new ArrayList<>();
    String [] choice = new String[2];
    public List<String> generateParenthesis(int n) {
        this.n = n;
        choice[0] = "(";
        choice[1] = ")";
        huisu("", 0 , 0);
        return ans;
    }

    public void huisu(String path, int leftParenthesisNum, int rightParenthesisNum) {
        if (leftParenthesisNum == n && leftParenthesisNum == rightParenthesisNum) {
            ans.add(path);
            return;
        }

        // 选择列表
        for (int i = 0; i < 2; i ++) {
            // 作出选择
            if (i == 0 && leftParenthesisNum == n) {
                continue;
            }
            if (i == 1 && rightParenthesisNum == leftParenthesisNum) {
                continue;
            }
            path = path + choice[i];
            if (i == 0) {
                huisu(path, leftParenthesisNum + 1, rightParenthesisNum);
            } else {
                // 添加右括号的前提是
                if (rightParenthesisNum < leftParenthesisNum) {
                    huisu(path, leftParenthesisNum, rightParenthesisNum + 1);
                }
            }

            // 撤销选择
            path = path.substring(0, path.length() - 1);
        }

    }

}

基本思路

  1. 遇见题目不要慌, 它问你字符串一共有哪些组成的可能, 和问你在方格里左上到右下的路径, 其实没啥差别, 都是从一个起点开始, 然后做一次选择, 最后选择结束, 得到一个可行的结果

  2. 根据题目, 需要得到n对括号, 不能存在无用的符号.

  3. 根据括号的特点, (1) 先有左括号, 才有右括号 (2) 有几个左括号, 就有几对括号 (3) 任何一个时刻, 右括号的数量, 不能超过左括号.

  4. 根据回溯的思想, 每次只有两个选择, 添加左括号还是右括号, 然后根据n, 左括号数量, 右括号数量来判断是否能选择, 然后递归, 然后撤销选择