代码随想录算法训练营第二十八天
LeetCode题目:
- 509. 斐波那契数
- 70. 爬楼梯
- 746. 使用最小花费爬楼梯
- 2444. 统计定界子数组的数目(每日一题)
其他:
今日总结
往期打卡
动态规划解题步骤:
- 确定递推公式
- 确定遍历顺序
- 记忆化搜索(确定dp数组以及下标的含义与初始化值)
- 递推优化与空间优化
509. 斐波那契数
跳转: 509. 斐波那契数
学习: 代码随想录公开讲解
问题:
斐波那契数 (通常用 F(n)
表示)形成的序列称为 斐波那契数列 。该数列由 0
和 1
开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n
,请计算 F(n)
。
思路:
递推公式,f(n-1)+f(n-2),前两个加一块
遍历顺序,从前往后到n,先求前面再求后面
计算时记录每个位置的值,初始化一个大小为n+1的数组,1为0,2为1,也可以初始化其他的为-1更好区分
发现每次只依赖前两个,如果递归改递推,就可以只用两个变量
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(递归):
class Solution {int[] f = new int[31];{f[1] = 1;f[0] = 0;}public int fib(int n) {if (n < 2)return f[n];if (f[n] > 0)return f[n];return f[n] = fib(n - 2) + fib(n - 1);}
}
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
代码(递推):
class Solution {public int fib(int n) {if(n==0) return 0;int f0 = 0;int f1 = 1;for(int i=1;i<n;i++){int tmp = f1;f1 = f1+f0;f0 = tmp;}return f1;}
}
70. 爬楼梯
跳转: 70. 爬楼梯
学习: 代码随想录公开讲解
问题:
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
思路:
前一个来或前前个来,递推公式是前两个的种数和
顺序遍历,从前往后
改递归更新每次依赖的两个
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
代码:
class Solution {public int climbStairs(int n) {int f0 = 1;int f1 = 1;for(int i=2;i<=n;i++){int newF = f0+f1;f0 = f1;f1 = newF;}return f1;}
}
746. 使用最小花费爬楼梯
跳转: 746. 使用最小花费爬楼梯
学习: 代码随想录公开讲解
问题:
给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
思路:
前一个来或前前个来,递推公式是取算上过来的代价的最小值
顺序遍历,从前往后
改递归更新每次依赖的两个
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
代码:
class Solution {public int minCostClimbingStairs(int[] cost) {int f0 = 0;int f1 = 0;for(int i=2;i<=cost.length;i++){int tmp = Math.min(f0+cost[i-2],f1+cost[i-1]);f0 = f1;f1 = tmp;}return f1;}
}
2444. 统计定界子数组的数目(每日一题)
跳转: 2444. 统计定界子数组的数目
学习: 灵茶山艾府公开讲解
问题:
给你一个整数数组 nums
和两个整数 minK
以及 maxK
。
nums
的定界子数组是满足下述条件的一个子数组:
- 子数组中的 最小值 等于
minK
。 - 子数组中的 最大值 等于
maxK
。
返回定界子数组的数目。
子数组是数组中的一个连续部分。
思路:
定右看左,最近合法位置减去最近越界位置的差值就是当前位置的合法子数组数
但差值可能来自上一个位置或由初始化得到,所以需要判断负数转0
最近合法位置就是最大与最小离当前位置最远的那个位置
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
代码:
class Solution {public long countSubarrays(int[] nums, int minK, int maxK) {int min_i,max_i,i0;min_i = max_i = i0 = -1;long ans = 0;for(int i=0;i<nums.length;i++){if(nums[i]==minK) min_i = i;if(nums[i]==maxK) max_i = i;if(nums[i]>maxK||nums[i]<minK) i0 = i;ans += Math.max(0,Math.min(min_i,max_i)-i0); }return ans;}
}
总结
练习了动态规划和子数组问题
往期打卡
代码随想录算法训练营第二十七天(补)
代码随想录算法训练营第二十六天
代码随想录算法训练营第二十五天
代码随想录算法训练营第二十四天
代码随想录算法训练营第二十三天
代码随想录算法训练营周末四
代码随想录算法训练营第二十二天(补)
代码随想录算法训练营第二十一天
代码随想录算法训练营第二十天
代码随想录算法训练营第十九天
代码随想录算法训练营第十八天
代码随想录算法训练营第十七天
代码随想录算法训练营周末三
代码随想录算法训练营第十六天
代码随想录算法训练营第十五天
代码随想录算法训练营第十四天
代码随想录算法训练营第十三天
代码随想录算法训练营第十二天
代码随想录算法训练营第十一天
代码随想录算法训练营周末二
代码随想录算法训练营第十天
代码随想录算法训练营第九天
代码随想录算法训练营第八天
代码随想录算法训练营第七天
代码随想录算法训练营第六天
代码随想录算法训练营第五天
代码随想录算法训练营周末一
代码随想录算法训练营第四天
代码随想录算法训练营第三天
代码随想录算法训练营第二天
代码随想录算法训练营第一天