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

目录

零、写在前面

一、主要知识点

   1.找到递推式

二、课后习题 

509. 斐波那契数

1137. 第 N 个泰波那契数(看上面那题)

119. 杨辉三角 II

70. 爬楼梯

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

剑指 Offer II 092. 翻转字符

写在最后


零、写在前面

        今天是打卡的第28天,今天好累,不过好多题都是之前做过的,下午没课我能睡一小会了,老规矩,知识点在:

《算法零基础100讲》(第28讲) 递推问题https://blog.csdn.net/WhereIsHeroFrom/article/details/121367086https://blog.csdn.net/WhereIsHeroFrom/article/details/121367086


一、主要知识点

   1.找到递推式

其实参考代码没啥用,主要是要找到递推式,才能更好的解题。学好数学-.-

long long getACM(int n) {
	long long g[40];
	g[1] = 3, g[2] = 8;
    for(i = 3; i <= n; i++) {
        g[i] = 2 * (g[i-1] + g[i-2]);
    }
    return g[n];
}

二、课后习题 

509. 斐波那契数

509. 斐波那契数https://leetcode-cn.com/problems/fibonacci-number/

题目描述

斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你 n ,请计算 F(n) 。

思路

这个我写过,但是我找不到了,,,其实就是利用空间来更新数组 得到最终的结果就好了。

int fib(int n){
    if(!n) return 0;
    int F[n + 1];//创建数组保存计算过的数字
    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 个泰波那契数https://leetcode-cn.com/problems/n-th-tribonacci-number/


119. 杨辉三角 II

119. 杨辉三角 IIhttps://leetcode-cn.com/problems/pascals-triangle-ii/

题目描述

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

思路

按照规则计算就好了,但是注意到F[n][i]= F[n-1][i-1]+F[n-1][i]

可以考虑一个问题就是节约空间的话 从后往前更新就好了? 

 我就记得我写过,在这里,,,之前写的实在排版脑子疼。。。凑合看 有时间我翻修一下

[题解]《算法零基础100讲》(第4讲) 组合数(c语言描述)https://bbs.csdn.net/topics/602771428


70. 爬楼梯

70. 爬楼梯https://leetcode-cn.com/problems/climbing-stairs/

题目描述

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

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

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

思路

很容易想到 F[n] = F[n-1]+F[n-2],也就是走到第n阶有两种方式 一种是从n-1走一阶到,另外一种从n-2阶梯走2台阶。直接写代码就完事了。

int climbStairs(int n){
    if(!n)  return 0;    //初始条件
    else if(n == 1) return 1;//初始条件
    else if(n == 2) return 2;//初始条件
    int ans[n];
    ans[0] = 1;//初始条件
    ans[1] = 2;//初始条件
    for(int i = 2;i<n;i++)
        ans[i] = ans[i-1]+ans[i-2];//计算
    return ans[n-1];//返回最大值
}

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

剑指 Offer 62. 圆圈中最后剩下的数字https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/

题目描述

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

思路

如果删掉一个元素是不是就只剩n-1一个元素了?

然后根据递归就好了 其实就是F(n,m)=(m%n+F(n-1,m))%n = (m+F(n-1,m)%10;

做了个小视频,大家直接看就好了。官方的题解给动画是错的!

int lastRemaining(int n, int m){
    int x = 0;
    for (int i = 2; i != n + 1; ++i) {
        x = (m + x) % i;    //根据递推式进行计算就好了
    }
    return x;
}

剑指 Offer II 092. 翻转字符

剑指 Offer II 092. 翻转字符https://leetcode-cn.com/problems/cyJERH/

题目描述

如果一个由 '0' 和 '1' 组成的字符串,是以一些 '0'(可能没有 '0')后面跟着一些 '1'(也可能没有 '1')的形式组成的,那么该字符串是 单调递增 的。

我们给出一个由字符 '0' 和 '1' 组成的字符串 s,我们可以将任何 '0' 翻转为 '1' 或者将 '1' 翻转为 '0'。

思路

遍历每个跳变点看在哪个跳变点的时候反转次数最少。

一开始计数count为所有的0的个数。表示在最开始就反转。

往后移动一个位置的时候 如果这个位置是0 那么翻转的次数减少一次 如果是1增加一次

int minFlipsMonoIncr(char * s){
    if(strlen(s) == 1)  return 0;
    int count = 0,min = 0;
    for(int i = 0;s[i];i++)
        if(s[i] == '0') count++;//统计在最前面反转的次数
    min = count;    //min初始值
    for(int i = 0;s[i];i++){
        if(s[i] == '0') count--;
        else count++;    //更新count
        min = min>count?count:min;//更新min
    }
    return min;
}

写在最后

挺好,很多之前的东西不够精致,得慢慢的改一改,回头看看之前真的写的好垃圾。。

猜你喜欢

转载自blog.csdn.net/qq_17593855/article/details/121375768