初入算法(二)-递归

首先谈论下什么是时间复杂度,以及常见的时间复杂度类型

时间复杂度:指执行算法所需要的计算工作量;
空间复杂度:指执行这个算法所需要的内存空间;

常见的类型有七种
O(1): 常数复杂度

int n=0;
cout<<n<<endl;

O(log n): 对数复杂度

for(int i=0;i<n;i*=2)
	cout<<i<<endl;

O(n):线性时间复杂度

for(int i=0;i<n;i++)
	.....

O(n^2): 平方

for(int 1=0;i<n;i++)
	for(int j=0;j<n;j++)
		.....

O(n^3):立方
与O(n^2)类似

O(2^n) : 指数
递归,则为指数形式的时间复杂度

O(n!):阶乘
n!

Now进入递归算法(目前最常用使用递归的一种结构为树)

在写递归函数时,常常使用的模板

  1. 递归的终止条件 terminator
  2. 处理当前的逻辑层 process current logic
  3. 下操下一层 drill down
  4. 清理当前层 restore current status
    在这里插入图片描述

由浅入深:
题目一:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶

示例 2:

输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶

解法一(递归,时间复杂度为2^n)

int climbStairs(int n)
{
    if(n<=2)
        return n;
    return climbStairs(n-1)+climbStairs(n-2);
}

n越大时,执行时间越长,一般不采用
解法二(循环,线性时间复杂度)

int climbStairs(int n)
{
    if(n==1)
        return 1;
    if(n==2)
        return 2;
    int f1=1;
    int f2=2;
    int allResult =0;
    for(int i=2;i<n;i++)
    {
        allResult=f1+f2;
        f1=f2;
        f2=allResult;
    }
    return allResult;
}

题目二:

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

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

[ “((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()” ]

核心思想:

  1. 先有左括号,才能有右括号
  2. 左括号数一定大于或者等于右括号数
void generate(vector<string>& strs,int left,int right,int n,string str)
    {
        //terminator
        if(left==n && right==n)
        {
            strs.push_back(str);
            return;
        }
        //process current logic

        //drill down
        if(left<n)
            generate(strs,left+1,right,n,str+"(");
        if(left>right)
            generate(strs,left,right+1,n,str+")");

        //restore current status
    }
    vector<string> generateParenthesis(int n) {
        vector<string> strs;
        generate(strs,0,0,n,"");
        return strs;
    }
发布了17 篇原创文章 · 获赞 3 · 访问量 416

猜你喜欢

转载自blog.csdn.net/qq_41172631/article/details/105119650