算法:阶乘与递归树

阶乘公式推导

F(0) = 1
F(1) = 1 * 1 = 1 * F(0)
F(2) = 2 * 1 = 2 * F(1)
F(3) = 3 * 2 * 1 = 3 * F(2)
F(n) = n * F(n-1)

在这里插入图片描述

  • 0的阶乘为社么是1
    • 阶乘是排列组合的数量, 比如三个东西排列组合有3! (=6)种方式
    • 那么如果没有东西,如何排列组合?
    • ——那就“不排列组合”。“什么都不做”可以当做一种方式,i.e: 0!=1.

实现

暴力递归

int Fab(int n) {
    if (n <= 1){
        return 1;
    }

    return n * Fab(n - 1);
}


int main(){
	Fab(4);
}

递归树如下
在这里插入图片描述

动态规划

(1)准备表。先看可变参数范围

 int Fab(int n)
  • 可变参数n,其取值范围: 1~N
  • 所以准备一个n+1长度的数组
std::vector<int> dp(n + 1)

(2)返回值。看主函数是怎么调用它的

Fab(n)
  • 应该返回dp[n];

(3)填表
(3.1)先初始化表。也就是看base case

    if (n <= 1){
        return 1;
    }
  • 所以,如下
dp[0] = 1;
dp[1] = 1;

(3.2) 再分析普通情况的依赖:

return n * Fab(n - 1);
  • 其依赖前一个,所以应该从左往右填
for(int i = 2; i <= n; i++){

}

综上:

int fab(int n){
    if(n <= 1){
        return 1;
    }


    std::vector<int> dp(n + 1);
    dp[0] = 1;
    dp[1] = 1;
    for(int i = 2; i <= n; i++){
        dp[i] = i * dp[i - 1];
    }

    return dp[n];
}

栈模拟递归

#include <cstdio>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <cstring>
#include <assert.h>
#include <stack>
using namespace std;

int Jie(int num){
    if(num == 1){
        return 1;
    }

    return num * Jie(num - 1);
}


int JieStack(int num){
    assert(num > 0);
    std::stack<int> stack;
    stack.push(num);

    int data = 0, ans = 1;
    while (!stack.empty()){
        data = stack.top();
        stack.pop();
        if(data == 1){
            ans = ans * 1;
        }else{
            ans = ans * data;
            stack.push(data - 1);
        }
    }

    return ans;
}


int main(int argc,char **argv){

    printf("%d\n", Jie(5));
    printf("%d\n", JieStack(5));

    return 0;
}

参考网站

递归树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值