【解题报告】《算法零基础100讲》(第28讲) 递推问题

前言

原文链接:《算法零基础100讲》(第28讲) 递推问题

509. 斐波那契数

原题链接:509. 斐波那契数

在这里插入图片描述

代码

根据题目意思直接写出

int fib(int n)
{
    if (n == 0) return 0;
    if (n == 1) return 1;

    int F[31] = {0};
    F[0] = 0, F[1] = 1;

    for (int i = 2; i <= n; ++i)
    {
        F[i] = F[i - 1] + F[i - 2];
    }

    return F[n];
}

1137. 第 N 个泰波那契数

原题链接:1137. 第 N 个泰波那契数

在这里插入图片描述

代码

一样是,根据题意来直接写

int tribonacci(int n)
{
     if (n == 0) return 0;
    if (n == 1 || n == 2) return 1;

    int T[38] = {};
    T[0] = 0, T[1] = T[2] = 1;

    for (int i = 3; i <= n; ++i)
    {
        T[i] = T[i - 1] + T[i - 2] + T[i - 3];
    }

    return T[n];
}

118. 杨辉三角

原题链接:118. 杨辉三角

在这里插入图片描述

代码与注释

int** generate(int numRows, int* returnSize, int** returnColumnSizes)
{
    //动态申请二维数组作为返回答案,题目要求numRows行
    int** ans = (int**)malloc(sizeof(int*) * numRows);
    if (ans == NULL) return NULL;

    //根据题意,*returnSize返回答案数组行的长度,即numRows行
    *returnSize = numRows;

    //这个数组保存的是每行有多少个元素,所以动态申请一个一维数组
    *returnColumnSizes = (int*)malloc(sizeof(int) * numRows);

    int i = 0, j = 0;

    //这个循环是从0到numRows,即想要遍历每一行数组
    //1.将为返回答案的二维数组的每一行动态申请一维数组,
    //2.并将每行的元素个数保存到*returnColumnSizes数组中
    //3.因为是杨辉三角,所以将返回答案的每一行的最左端和最右端置为1.
    for (i = 0; i < numRows; ++i)
    {
        ans[i] = (int*)malloc(sizeof(int) * (i + 1));
        (*returnColumnSizes)[i] = i + 1;
        ans[i][0] = ans[i][i] = 1;
    }

    //这个双重循环,外层控制每行,内层对每行依次赋值
    for (i = 2; i < numRows; ++i)
    {
        for (j = 1; j < i; ++j)
        {
            ans[i][j] = ans[i - 1][j - 1] + ans[i - 1][j];
        }
    }

    //返回答案
    return ans;
}

119. 杨辉三角 II

原题链接:119. 杨辉三角 II

在这里插入图片描述

代码

int* getRow(int rowIndex, int* returnSize)
{
    //申请一维数组
    int* ans = (int*)malloc(sizeof(int) * (rowIndex + 1));
    memset(ans, 0, sizeof(int) * (rowIndex + 1));

    //先将第一行初始化
    ans[0] = 1;

    for (int i = 1; i < rowIndex + 1; ++i)
    {
        //从后往前处理
        for(int j = i; j > 0; --j)
        {
            //性质:每位元素都是它上一行的左右两数和
            ans[j] = ans[j - 1] + ans[j];
        }
    }

    //返回长度和数组
    *returnSize = rowIndex + 1;
    return ans;
}

70. 爬楼梯

原题链接:70. 爬楼梯

在这里插入图片描述

分析

设第 x 阶的方案为f(x),f(x)为 :

f(x) = f(x - 1) + f(x - 2)

再根据

f(0) = 1, f(1) = 1

即可求解

代码

int climbStairs(int n)
{
    int p = 0, q = 0, r = 1;

    for (int i = 1; i <= n; ++i)
    {
        p = q;
        q = r;
        r = p + q;
    }

    return r;
}

剑指 Offer 62. 圆圈中最后剩下的数字

原题链接:剑指 Offer 62. 圆圈中最后剩下的数字

在这里插入图片描述

分析

长度为 n 的序列会先删除第 m % n 个元素,然后剩下一个长度为 n - 1 的序列。那么可以递归地求解 f(n - 1, m)。设答案为 x = f(n - 1, m)。

f(n,m)=[(m - 1) % n + x + 1] % n
      =[(m - 1) % n % n + (x + 1) % n] % n
      =[(m - 1) % n + (x + 1) % n] % n
      =(m - 1 + x + 1) % n
      =(m + x) % n

代码

int f(int n, int m)
{
    if (n == 1)
        return 0;
    
    int x = f(n - 1, m);
    return (m + x) % n;
}

int lastRemaining(int n, int m)
{
    return f(n, m);
}

剑指 Offer II 092. 翻转字符

原题链接:剑指 Offer II 092. 翻转字符

在这里插入图片描述

代码

int minFlipsMonoIncr(char * s)
{
    if (NULL == s)
        return 0;
    
    int len = strlen(s);
    int count_0 = 0, count_1 = 0;

    for (int i = 0; i < len; ++i)
    {
        if (s[i] == '0')
        {
            count_1 = fmin(count_0, count_1) + 1;
        }
        else
        {
            count_1 = fmin(count_0, count_1);
            count_0++;
        }
    }

    return fmin(count_0, count_1);
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_索伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值