三天一题-25-Generate Parentheses

题目地址:Generate Parentheses
描述:
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
大意:给你n组圆括号,写出符合规则的方法,规则如下面的例子。

相关知识点:
[借鉴链接](https://www.cnblogs.com/smuxiaolei/p/7505391.html)
⭕️ 递归是一种算法结构,回溯是一种算法思想。
⭕️ 一个递归就是在函数中调用函数本身来解决问题。
⭕️ 回溯就是通过不同的尝试来生成问题的解,有点类似于穷举,但是和穷举不同的是回溯会“剪枝”。
⭕️ 回溯搜索是深度优先搜索(DFS)的一种,对于某一个搜索树来说(搜索树是起记录路径和状态判断的作用),回溯和DFS,其主要的区别是,回溯法在求解过程中不保留完整的树结构,而深度优先搜索则记下完整的搜索树。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class GenerateParentheses {
    public static void main(String[] args) {
        //方法1:自己写的,使用的是全排列,然后筛选
        //  Set<String> strings = generateParenthesisDemo(4);
        //方法2:摘自https://leetcode.com/problems/generate-parentheses/discuss/10100/Easy-to-understand-Java-backtracking-solution
        List<String> strings = generateParenthesis(3);
        System.out.println(strings);
    }

    private static Set<String> generateParenthesisDemo(int n) {
        Set<String> res = new HashSet<>();
        String[] arr = new String[2 * n];
        for (int i = 0; i < 2 * n - 1; i += 2) {
            arr[i] = "(";
            arr[i + 1] = ")";
        }
        allSort(0, arr.length, arr, res);
        return res;
    }

    //全排列然后去重并且筛选条件,使用DFS思想全部得出,然后再从中筛选中符合题目的。
    private static void allSort(int sortNum, int size, String[] arr, Set<String> res) {
        int zero = 0;
        String ex;
        //大的框架是全排列
        if (sortNum == size - 1) {
            StringBuffer param = new StringBuffer();
            for (int i = 0; i < size; i++) {
                //筛选条件:当左括号的时候zero加1
                if (arr[i].equals("(")) {
                    zero++;
                }
                //当存在左括号的时候,再判断右括号。
                if (zero > 0 && arr[i].equals(")")) {
                    zero--;
                }
                param.append(arr[i]);
            }
            if (zero == 0) {
                res.add(param.toString());
            }
        } else {
            int temp = sortNum;
            while (temp < size) {
                allSort(sortNum + 1, size, arr, res);
                if (temp < size - 1) {
                    ex = arr[temp + 1];
                    arr[temp + 1] = arr[sortNum];
                    arr[sortNum] = ex;
                }
                temp++;
            }
        }
    }


    //方法2 回溯思想。DFS的时候进行条件的判断,当不满足时进行剪枝。
    public static List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<String>();
        backtrack(list, "", 0, 0, n);
        return list;
    }

    public static void backtrack(List<String> list, String str, int open, int close, int max) {
        //深度等于2n的时候,结束本次搜索,退到上个节点
        if (str.length() == max * 2) {
            list.add(str);
            return;
        }
        //左括号必须小于n
        if (open < max)
            backtrack(list, str + "(", open + 1, close, max);
        //右括号需小于左括号的数目
        if (close < open)
            backtrack(list, str + ")", open, close + 1, max);
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值