算法刷题笔记——括号生成

请你写一个算法,输入是一个正整数 n,输出是 n 对儿括号的所有合法组合,

比如说,输入 n=3,输出为如下 5 个字符串:

"((()))", "(()())", "(())()", "()(())", "()()()"

 

C++:

#include 
#include 
#include 
using namespace std;



// 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
void backtrack(int left, int right, string& track, vector& res) 
{
		// 若左括号剩下的多,说明不合法
		if (right < left) return;
		// 数量小于 0 肯定是不合法的
		if (left < 0 || right < 0) return;
		// 当所有括号都恰好用完时,得到一个合法的括号组合
		if (left == 0 && right == 0) {
			res.push_back(track);
			return;
		}

		// 尝试放一个左括号
		track.push_back('('); // 选择
		backtrack(left - 1, right, track, res);
		track.pop_back(); // 撤消选择

		// 尝试放一个右括号
		track.push_back(')'); // 选择
		backtrack(left, right - 1, track, res);
		track.pop_back();   // 撤消选择
}

vector generateParenthesis(int n) {
	
	// 记录所有合法的括号组合
	vector res;
	if (n == 0) 
		return res;
	// 回溯过程中的路径
	string track;
	// 可用的左括号和右括号数量初始化为 n
	backtrack(n, n, track, res);
	return res;
}

void main()
{
	vector res;
	res = generateParenthesis(3);
	for (int i=0;i

 

Java:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Solution01 {
    public int generateParenthesis(int n) {
        List res = new ArrayList<>();
        // 特判
        if (n == 0) {
            return res.size();
        }

        // 执行深度优先遍历,搜索可能的结果
        dfs("", n, n, res);
        return res.size();
    }

    /**
     * @param curStr 当前递归得到的结果
     * @param left   左括号还有几个没有用掉
     * @param right  右边的括号还有几个没有用掉
     * @param res    结果集
     */
    private void dfs(String curStr, int left, int right, List res) {
        // 因为是递归函数,所以先写递归终止条件
        if (left == 0 && right == 0) {
            res.add(curStr);
            return;
        }

        // 因为每一次尝试,都使用新的字符串变量,所以没有显式的回溯过程
        // 在递归终止的时候,直接把它添加到结果集即可,与「力扣」第 46 题、第 39 题区分

        // 如果左边还有剩余,继续递归下去
        if (left > 0) {
            // 拼接上一个左括号,并且剩余的左括号个数减 1
            dfs(curStr + "(", left - 1, right, res);
        }
        // 什么时候可以用右边?例如,((((((),此时 left < right,
        // 不能用等号,因为只有先拼了左括号,才能拼上右括号
        if (right > 0 && left < right) {
            // 拼接上一个右括号,并且剩余的右括号个数减 1
            dfs(curStr + ")", left, right - 1, res);
        }
    }

    public static void main(String[] args) {
        Solution01 s1 = new Solution01();
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        System.out.println(s1.generateParenthesis(n));
    }
}

 

你可能感兴趣的:(算法刷题笔记)