careercup-递归和动态规划 9.6

9.6 实现一种算法,打印n对括号的全部有效组合(即左右括号正确配对)。

类似leetcode:Generate Parentheses

解法:

从头开始构造字符串,从而避免出现重复字符串。在这个解法中,逐一加入左括号和右括号,只有字符串仍然有效。每次递归调用,都会有个索引指向字符串的某个字符。我们需要选择左括号或右括号,那么,何时可以用左括号,何时可以用右括号呢?

左括号:只有左括号还没有用完,就可以插入左括号

右括号:只有不造成语法错误,就可以插入右括号。何时出现语法错误?如果右括号比左括号还多,就会出现语法错误。

因此,我们只需记录允许插入的左右括号数目。如果还有左括号可用,就插入一个左括号然后递归。如果右括号比左括号好多(也就是使用中的左括号比右括号还多),就插入一个右括号然后递归。

C++实现代码:

#include<iostream>
#include<vector>
#include<string>
using namespace std;

void helper(int left,int right,vector<string> &res,string &str)
{
    if(left>right)
        return;
    if(left==0&&right==0)
    {
        res.push_back(str);
        return;
    }
    if(left>0)
    {
        str+='(';
        helper(left-1,right,res,str);
        str.pop_back();
    }
    if(right>0)
    {
        str+=')';
        helper(left,right-1,res,str);
        str.pop_back();
    }
}
vector<string> generateParens(int n)
{
    if(n<=0)
        return vector<string>();
    vector<string> ret;
    string path;
    helper(n,n,ret,path);
    return ret;

}

int main()
{
    vector<string> res=generateParens(3);
    for(auto a:res)
        cout<<a<<endl;
}

 

时间: 2024-09-28 02:45:32

careercup-递归和动态规划 9.6的相关文章

字符串相似度算法 递归与动态规划求解分析

1.概念 编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数.许可的编辑操作包括:(1)将一个字符替换成另一个字符,(2)插入一个字符,(3)删除一个字符. 相似度,等于"编辑距离+1"的倒数. 2.分析 设有字符串a[0...n],b[0...m]. (1)当a[i]=b[j]时,说明这时候不需要编辑操作.编辑距离保持,即f(i,j)=f(i-1,j-1) (2)当a[i]!=b[j]时,可以有三种编辑操作. 其中删除和插入操作,只对一个下标i或者j产生影响.如

动态规划与递归联系。

问题描述 动态规划与递归联系. 求教各位,以前一直觉得动态规划就是对递归的优化,最近发现并不是.我想请问各位动态规划和递归之间有什么联系吗?还是说动态规划和递归没关系. 解决方案 动态规划和递归毫无关系,事实上也没有"递归优化"这种说法. 动态规划的思想是将要解决的问题转化为一系列逐步求解的问题并且逐步加以解决.动态规划避免了无意义的穷举,它强调逐步解决问题,让先前解决的结果可以作为后续解决问题的条件避免重复求解相同的问题. 举一个例子,最长公共子序列问题(我曾经解答过,完整代码在这里

动态规划算法

斐波纳契数列F(n) n 0 1 2 3 4 5 6 7 8 9 10 F(n) 1 1 2 3 5 8 13 21 34 55 89 递归 vs 动态规划 递归版本(太慢): int f(int n) { if(n <= 1) return 1; else return f(n-1)+f(n-2); } 动态规划版本(有效率!算法复杂度是 O(n)): int a[1000]; int f(int n) { a[0]=a[1]=1; for(int i=2; i<=n; i++) a[i]=

动态规划总结

动态规划 终于来到了算法设计思想中最难,也最有趣的这部分,在去年的google笔试中,7道算法设计题有2道动态规划(Dynamic Programming). 看了这么久的算法,这部分也是唯一感觉到了比较难的地方, 从这篇文章开始,将花连续的篇幅来讨论一些动态规划的问题.这包括书上介绍过的计算二项式系数,Warshall算法求传递闭包,Floyd算法求完全最短路径,构造最 有二叉查找树,背包问题和记忆功能.也包括一些其他问题的解题报告(动态规划确实很难,对这一章的内容,我将搜索一些其他类型的问题

两道有趣的面试题(转)

题目一 竹筒有20根签,10根白色,10根红色.抽取10根颜色一致可获得100元奖励,抽取9根颜色一致可获得50元奖励,但是抽取红色5根白色5根就损失50元,问这游戏是否值得参与?原因?   解: 这是典型的组合数求期望问题.设事件'抽取10根颜色一致'为A,事件'抽取9根颜色一致'为B,事件'抽取红色5根白色5根'为C. 根据组合数公式 C(m.n) = m!/(n!*(m-n)!) 求得事件A的概率P(A) = C(10,10)*2/C(20,10) = 0.0000108250882244

世界五百强面试题求解,看似超简单,但是。。。

问题描述 Stringinput="ABABABA";写算法求所有符合A$A的字符串的数量,其中$代表A-Z之间至少一个字符.我一看tnd不就是正则吗?迅速写出答案:Stringregex="A[A-Z]+A";Patternp=Pattern.compile(regex,Pattern.CASE_INSENSITIVE);Matcherm=p.matcher(input);while(m.find()){System.out.println(m.group());

动态规划(DP)入门

零.先修课程 首先,在开始理解DP的思想前,你需要 1. 完成HDU里面的递推求解专题练习(For Beginner)那7道题(这些题很简单,题解请在博客中搜索),这对你理解DP有很大的帮助. 2. 对递归搜索(比如深度优先搜索,DFS)有一定了解. 一.递归与记忆化搜索 我们从POJ 3176入手来学习这一思想.(题目很短,请快速读完) 从上往下看,最大和值无非是往左走和往右走这两条路的较大者.这样,我们可以写出下面这个重要的递归函数:(这里i表示行,j表示列) int f(int i, in

用动态规划算法对最大子串问题的java实现

最大字串问题描述大概就是给定2个字符串,找出他们两个共有的最长字符串.比如一个是"tabcfg"另外一个"abckj"那么最大子串就是"abc". 动态规划算法最重要的就是分解问题,找出递归.说一下我的思考思路,首先拿到2个字符串,如何找到最长子串呢? 1.假设他们(字符串a,b)的头字母不相同的话,那么分别去掉首字母比较,也就是说用a.subString(1)和b比较,用 b.subString(1)和a比较,最长子字符串没变吧?答案是肯定的.

我对递归的认识

首先明确一点: 递归是不符合人自然的逻辑思维的,需要训练. (1)递归的例子 求5的阶乘 /*** * 阶乘 * @param n * @return */ public static int arrayArrange(int n){ if(n<2){ return 1; }else{ return n*arrayArrange(n-1); } } arrayArrange方法体中调用了自身,只是参数不同. 求1到100的和 public static int getSum(int n){ if

一些常见的递归算法 动态规划算法

最大值的递归算法 对于一个数组 有A[ 1...n ] 算法调用的时候调用max(n) max(i) if i = 1 return A[i] else if A[i]>max(i-1) return A[i] else return max(i-1) end if end if 平均值的递归算法 对于数组 a[ 1...n ] sum 初值为 0 index 初值则为1 调用该算法使用 Ave(a,sum,index) Ave(int a[],int sum,int index) if(ind