121.买卖股票的最佳时机&70.爬楼梯
买卖股票的最佳时机
给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回0。
示例1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
解题思路
暴力法
穷举,实际就是两层循环,时间复杂度为O(n^2),空间复杂度为O(1)。(会超出时间限制
class Solution {
public:
int maxProfit(vector<int>& prices) {
int length=prices.size();
int rtn=0;
for(int i=0;i<length;i++)
{
for(int j=i+1;j<length;j++)//j从i+1开始,表示依次判断第i天之后的收益情况
{
rtn=max(rtn,prices[j]-prices[i]);
}
}
return rtn;
}
};
动态规划法
化大为小,总体思路:前i天的最大收益为取最大值{前i-1天的最大收益,第i天的收益},公式:前i天的最大收益=max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}
class Solution {
public:
int maxProfit(vector<int>& prices) {
int length=prices.size();
if(length<=1)return 0;
//维护一个最大收益随时更新,一个i-1天中的最小支出
int beforeMin=prices[0];
int maxprofit=0;
for(int i=1;i<length;i++)
{
maxprofit=max(maxprofit,prices[i]-beforeMin);//套用公式
beforeMin=min(beforeMin,prices[i]);//更新前i-1天的最小价格,为后面的i做准备
}
return maxprofit;
}
};
爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1阶 +1阶
2阶
示例2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1阶 + 1阶 + 1阶
1阶 + 2阶
2阶 + 1阶
解题思路
动态规划:
- 要么从第n-1阶台阶,要么从n-2阶台阶跳上第n级台阶,得到递推公式:f(n)=f(n−1)+f(n−2)
- 边界条件:只有一阶台阶的时候有一种方法f(1) = 1f(1)=1;只有两阶台阶的时候有两种方法f(2)=2f(2)=2
class Solution {
public:
int climbStairs(int n) {
int rtn[3]={1,2,3};
if(n<4)return rtn[n-1];
for(int i=3;i<n;i++)
{
rtn[0]=rtn[1];
rtn[1]=rtn[2];
rtn[2]=rtn[1]+rtn[0];
}
return rtn[2];
}
};
矩阵快速幂
以斐波那契数列为例:
https://leetcode-cn.com/problems/fibonacci-number/solution/mian-shi-ti-wen-jin-yi-bu-you-hua-chao-x-aeqe/
https://leetcode-cn.com/problems/fibonacci-number/solution/fei-bo-na-qi-shu-by-leetcode-solution-o4ze/
- 快速幂运算原理:对于求a的n次幂(a可以是数也可以是矩阵),先判断幂次的奇偶性
- 如果是偶数——底数平方,指数除以2
- 如果是奇数——底数平方,指数除以2,再乘一次底数
我们在计算一个数的多次幂时,可以先判断其幂次的奇偶性,然后:
以求 3^10 的结果为例:
3^10=3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3
=9^5 = 9^4 * 9
=81^2 * 9
=6561 * 9
- 对于以上涉及到 [判断奇偶性] 和 [除以2] 这样的操作。使用系统的位运算比普通运算的效率是高的,因此可以进一步优化:
- 把 power % 2 == 1 变为 (power & 1) == 1
- 把 power = power / 2 变为 power = power >> 1
class Solution {
public:
int fib(int n) {
/*对于n=1和n=2直接返回对应的值*/
if (n < 2) {
return n;
}
vector<vector<int>> q{{1, 1}, {1, 0}};
vector<vector<int>> res = matrix_pow(q, n - 1);//根据上图公式,计算矩阵的n-1次幂
return res[0][0];
}
vector<vector<int>> matrix_pow(vector<vector<int>>& a, int n) {
vector<vector<int>> ret{{1, 0}, {0, 1}};
while (n > 0) {
if (n & 1) {//如果是奇数的话 需要多乘一次底数
ret = matrix_multiply(ret, a);
}
n >>= 1;
a = matrix_multiply(a, a);
}
return ret;
}
/*矩阵相乘的函数*/
vector<vector<int>> matrix_multiply(vector<vector<int>>& a, vector<vector<int>>& b) {
vector<vector<int>> c{{0, 0}, {0, 0}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
}
}
return c;
}
};
本题代码(官方解答):
class Solution {
public:
vector<vector<long long>> multiply(vector<vector<long long>> &a, vector<vector<long long>> &b) {
vector<vector<long long>> c(2, vector<long long>(2));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
}
}
return c;
}
vector<vector<long long>> matrixPow(vector<vector<long long>> a, int n) {
vector<vector<long long>> ret = {{1, 0}, {0, 1}};
while (n > 0) {
if ((n & 1) == 1) {
ret = multiply(ret, a);
}
n >>= 1;
a = multiply(a, a);
}
return ret;
}
int climbStairs(int n) {
vector<vector<long long>> ret = {{1, 1}, {1, 0}};
vector<vector<long long>> res = matrixPow(ret, n);
return res[0][0];
}
};
关于快速幂次运算见下题:
Pow(x,n)
实现pow(x, n) ,即计算x的n次幂函数(x^n)。
示例1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例2:
输入:x = 2.10000, n = 3
输出:9.26100
示例3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
解题思路
class Solution {
public:
double myPow(double x, int n) {
double rtn=1.0;
for(int i=n;i!=0;i/=2)
{
if(i&1)rtn*=x;
x*=x;
}
return n<0?1/rtn:rtn;//如果幂次小于0,返回rtn的倒数
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】