zoukankan      html  css  js  c++  java
  • [LeetCode] 22. 括号生成(回溯/DP)

    题目

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

    例如,给出 n = 3,生成结果为:

    [
    "((()))",
    "(()())",
    "(())()",
    "()(())",
    "()()()"
    ]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/generate-parentheses
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题解

    方法一 回溯

    • 回溯法使用递归,并在递归过程中考虑剪枝。此外,递归要考虑终止条件,考虑传的参数,参数可以包括结果的集合,一直要用的变的量,随着递归层数不同变化的计数量,临时的作为最终结果的str。
    • 此题目中,从长度为0到长度为2n递归生成一组有效括号组合,满足条件的下一层递归分支才进入(即进行了剪枝):当当前左括号数量<n时,可以加一个左括号;当当前右括号数量小于左括号数量时,可以加一个右括号。这样保证所有生成的括号都是有效的。

    方法二 DP

    • 大概递归思想: dp[n]='('+dp[i]+')'+dp[n-1-i] ,n 从0到用户输入的N,对于计算dp[n]遍历所有可能的i,,其中dp[n]表示长度为2*n的所有有效串。
    • 存储方法也很有意思,用List<List> ans,最终用ans.get(n)获得长度为2*n的所有有效括号组合。
    • 方法一二的时间复杂度相同,都只遍历了有效的分支,且没有重复。?

    代码

    代码一 回溯

    class Solution {
    	public static List<String> generateParenthesis(int n) {
    		List<String> parenthesis = new ArrayList<>();
    		traceBack("", 0, 0, n, parenthesis);
    		return parenthesis;
    	}
    
    	private static void traceBack(String str, int left, int right, int n,
    			List<String> parenthesis) {
    		if (str.length() == 2 * n) {
    			parenthesis.add(new String(str));
    			return;
    		}
    		if (left < n) {
    			traceBack(str + '(', left + 1, right, n, parenthesis);
    		}
    		if (right < left) {
    			traceBack(str + ')', left, right + 1, n, parenthesis);
    		}
    	}
    }
    

    代码二 DP

    class Solution {
       public List<String> generateParenthesis(int n) {
    		List<List<String>> parenthesis = new ArrayList<>();// 所有长度<=2n的括号组合
    
    		// 将长度为0的括号组合,放入parenthesis
    		ArrayList<String> list = new ArrayList<>();
    		list.add("");
    		parenthesis.add(list);
    
    		// 由nn为1至n一层层算2*nn长度的括号组合,放入parenthesis
    		for (int nn = 1; nn <= n; ++nn) {
    			List<String> parenthesisTemp = new ArrayList<>();
    			for (int leftLen = 0; leftLen <= nn - 1; ++leftLen) {
    				for (String leftStr : parenthesis.get(leftLen)) {
    					for (String rightStr : parenthesis.get(nn - 1 - leftLen)) {
    						parenthesisTemp.add(new String('(' + leftStr + ')' + rightStr));
    					}
    				}
    			}
    			parenthesis.add(parenthesisTemp);
    		}
    
    		return parenthesis.get(n);
    	}
    }
    
  • 相关阅读:
    Leetcode 121. Best Time to Buy and Sell Stock
    Leetcode 120. Triangle
    Leetcode 26. Remove Duplicates from Sorted Array
    Leetcode 767. Reorganize String
    Leetcode 6. ZigZag Conversion
    KMP HDU 1686 Oulipo
    多重背包 HDU 2844 Coins
    Line belt 三分嵌套
    三分板子 zoj 3203
    二分板子 poj 3122 pie
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/12070496.html
Copyright © 2011-2022 走看看