给定数字生成括号组合

生成括号

题目描述:

n=3 3个左括号+3个右括号
合法:((())) (())() (()())
非法:)()()(

要求: 找出所有合法的括号情况

思路1: 暴力枚举

生成数组1,全部装左括号。
生成数组2,全部装右括号。
对数组1、数组2,里的内容进行排列组合,枚举出所有的情况。
对枚举出的情况进行合法检查,可用栈,遇到左括号,入栈;遇到右括号,弹出栈元素。

思路2: 用回溯,剪枝。

对于明显的非法情况,可直接排除剪枝:第一个是右括号,最后一个是左括号。
对于每个位置,可以放左括号,也可以放右括号。 使用数组依次递归下去。

Java 代码实现:

public class Main {

    public List<String> get(int n) {
        Set<String> res = new HashSet<>();
        put(new String[2 * n], 0, "(", res);

        return new ArrayList<>(res);
    }

    private void put(String[] arr, int putIndex, String content, Set<String> res) {
        if (putIndex == arr.length) {
            res.add(arrToString(arr));
            return;
        }


        arr[putIndex] = content;
        int leftCount = 0;
        int rightCount = 0;
        for (String s : arr) {
            if (s == null) {
                break;
            }
            if (s.equals("(")) {
                leftCount++;
            } else if (s.equals(")")) {
                rightCount++;
            }
        }

        if (illegalStatus(arr, leftCount, rightCount)) {
            arr[putIndex] = null;
            return;
        }


        put(arr, putIndex + 1, ")", res);
        if (leftCount <= arr.length / 2) {
            put(arr, putIndex + 1, "(", res);
        }

        arr[putIndex] = null;

    }

    private static String arrToString(String[] arr) {
        StringBuilder temp = new StringBuilder();
        for (String s : arr) {
            temp.append(s);
        }
        return temp.toString();
    }

    private static boolean illegalStatus(String[] arr, int leftCount, int rightCount) {
        return rightCount > leftCount || leftCount > arr.length / 2;
    }


    public static void main(String[] args) {
        Main main = new Main();
        List<String> strings = main.get(3);
        for (String string : strings) {
            System.out.println(string);
        }

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值