LeetCode刷题 Day38
509. Fibonacci Number
The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), for n > 1.
Given n, calculate F(n).
Example 1:
Input: n = 2
Output: 1
Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.
Example 2:
Input: n = 3
Output: 2
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.
Example 3:
Input: n = 4
Output: 3
Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.
思路:
- 定义dp数组以及下标含义: i为第i个数,dp[i]为第i个斐波那契数值
- 确定递推公式: 题目中给了 dp[n] = dp[n - 1] + dp[n - 2]
- dp数组初始化: 题目中大致也给了 dp[0] = 0, dp[1] = 1。其余都是0
- 确定遍历顺序: 因为是基于dp[0],dp[1]得到最终结果。所以是从左到右
- 举例推导数组,打印数组
代码:
var fib = function(n) {
//define dp arry
let dp = Array(n + 1).fill(0);
dp[0] = 0;
dp[1] = 1;
for (let i = 2; i < dp.length; i++) {
dp[i] = dp[i - 2] + dp[i - 1];
}
return dp[n]
};
时间复杂度: O(n), 空间复杂度: O(n)
也可以压缩一下空间,通过有限个变量来模拟整个滚动过程:
var fib = function(n) {
let first = 0;
let second = 1;
if (n < 1) return first;
if (n < 2) return second;
let third = 0;
for (let i = 2; i <= n; i++) {
third = first + second;
first = second;
second = third;
}
return third;
};
时间复杂度: O(n), 空间复杂度: O(1)
70. Climbing Stairs
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Example 1:
Input: n = 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input: n = 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
思路:
- 定义dp下标和数值: 0为第一步的选择个数,1为第二步的选择个数
- 确定递推公式: 这个和斐波那契数列数列是相同的,dp[i] = dp[i - 1] + dp[i - 2]
- dp数组的初始化: dp[0]为1, dp[1]为2,其余为0
- 确定遍历顺序: 从左到右
- 打印dp数组
代码:
var climbStairs = function(n) {
let dp = Array(n).fill(0);
dp[0] = 1;
dp[1] = 2;
for (let i = 2; i < n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n - 1];
};
时间复杂度: O(n), 空间复杂度: O(n)
类似于斐波那契数列问题,也可以压缩空间来做这样空间复杂度就是O(1)
746. Min Cost Climbing Stairs
You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps.
You can either start from the step with index 0, or the step with index 1.
Return the minimum cost to reach the top of the floor.
Example 1:
Input: cost = [10,15,20]
Output: 15
Explanation: You will start at index 1.
- Pay 15 and climb two steps to reach the top.
The total cost is 15.
Example 2:
Input: cost = [1,100,1,1,1,100,1,1,100,1]
Output: 6
Explanation: You will start at index 0.
- Pay 1 and climb two steps to reach index 2.
- Pay 1 and climb two steps to reach index 4.
- Pay 1 and climb two steps to reach index 6.
- Pay 1 and climb one step to reach index 7.
- Pay 1 and climb two steps to reach index 9.
- Pay 1 and climb one step to reach the top.
The total cost is 6.
思路:
- dp数组的i下标和数值含义: 0为第一个位置, 1为第二个位置, n为最后到达的位置。数值dp[0]为第一个位置时的消耗,dp[1]为第二个位置时的消耗,以此类推
- 递推公式: 因为是要计算最小的消耗且要加上cost[i]: dp[i] = (dp[i - 1], dp[i - 2]) + cost[i]。
- 初始化: dp长度可以为cost.length 也可以为 cost.length + 1。这里采用cost.length + 1的方法。这样最后一步的cost[cost.length]为NaN, 手动设置为0。dp[0] = cost[0], dp[1] = cost[1]。
- 确定遍历顺序: 从左到右
- 打印dp
代码:
var minCostClimbingStairs = function(cost) {
let n = cost.length;
let dp = Array(n + 1).fill(0);
dp[0] = cost[0];
dp[1] = cost[1];
if (n === 2) return Math.min(dp[0], dp[1]);
for (let i = 2; i <= n; i++) {
let actualCost = cost[i] ? cost[i] : 0;
dp[i] = actualCost + Math.min(dp[i - 1], dp[i - 2]);
}
return dp[n];
};
时间复杂度: O(n) 空间复杂度: O(n)