打卡!!!每日一题
今天继续给大家分享一道动态规划类型的题目。
题目描述:
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
题目示例:
可能之前有读过我打卡过的题目就知道,我们遇到动态规划类型的题目,一定不要上来就盲目的就写代码,一定要找其规律,这个规律就是解决问题的关键:状态转移方程
当然这道题,直接暴力解决,代码很好写,可是不一定能通过测试案例,我先把暴力解决的方案给出来:
public int maxProfit(int[] prices) {
int length = prices.length;
if (length <= 1) return 0;
int[] dp = new int[length];
for (int i = 0; i < length - 1; i++) {
int max = 0;
for (int j = i + 1; j < length; j++) {
int diff = prices[j] - prices[i];
max = max < diff ? diff : max;
}
dp[i] = max;
}
int max = dp[0];
for (int i = 1; i < length; i++) {
max = max < dp[i] ? dp[i] : max;
}
return max;
}
思路很简单,把每一天买入时对应的最大利润求出来,然后找最大值就好,然后看一下运行结果:
说明o(n^2)的时间复杂度不行,我们就只能乖乖的去思考其动态规划的思想了。
我们先定义
- 买入的最低点 min=prices[0],注意:min永远是最低的买入点
- dp[i]:表示在第i天所赚的差价,则我们不断的和最低点作对比
若prices[i]<min,说明最低点为price[i],更新min值为price[i],则dp[i]=0
若price[i]>=min,计算第i天的收益dp[i]=price[i]-min;
最后我们找出dp[i]中的最大值。
代码如下:
public int maxProfit(int[] prices) {
int length=prices.length;
if(length<=1)return 0;
int []dp=new int[length];
dp[0]=0;
int min=prices[0];
for(int i=1;i<length;i++){
if(prices[i]<min){
dp[i]=0;
min=prices[i];
}else{
dp[i]=prices[i]-min;
}
}
int max=dp[0];
for(int i=1;i<length;i++){
max=max<dp[i]?dp[i]:max;
}
return max;
}
不用看结果都知道这种方案要比 暴力解决效率高,最明显的就是时间复杂由o(n^2)变为o(n)
后面为继续为大家每日分享一题,也欢迎大家一起来打卡,共同进步!!!