121. 买卖股票的最佳时机
题目
给定一个数组 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。
提示:
1 <= prices.length <= 105
0 <= prices[i] <= 104
解题方法一
/**
* 暴力循环 超出时间限制
*
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)。只使用了常数个变量。
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int maxProfit = 0;
for (int i = 0; i < prices.length; i++) {
for (int j = i + 1; j < prices.length ; j++) {
if ((prices[j] - prices[i]) > maxProfit)
maxProfit = prices[j] - prices[i];
}
}
return maxProfit;
}
解题方法二
/**
* 一次遍历
* 时间复杂度:O(n),只需要遍历一次。
* 空间复杂度:O(1),只使用了常数个变量。
* @param prices
* @return
*/
public int maxProfit2(int[] prices) {
if(prices.length <= 1) return 0;
// 用一个变量记录一个历史最低价格 minprice,假设自己的股票是在那天买的
int minprice = Integer.MAX_VALUE;
int maxprofit = 0;
for (int i = 0; i < prices.length; i++) {
if (prices[i] < minprice) {
minprice = prices[i];
} else if (prices[i] - minprice > maxprofit) {
// 在第 i 天卖出股票能得到的利润就是 prices[i] - minprice
maxprofit = prices[i] - minprice;
}
}
return maxprofit;
}
解题方法三
解题思路
根据题意,股票只能先买后卖,即答案只能由数组后面的元素减去前面的元素获得
因此采用从后往前遍历的方法。
根据题意,需要找到数组后面的元素与前面元素的最大差值。
所以创建max
和min
变量来存储最大与最小值,再加上一个答案变量maxProfit
,这三个变量就是我们需要维护的全部变量。
在从后往前遍历的过程中,会遇到三种情况:
- 当前遍历到的元素介于
max
和min
之间 - 当前遍历到的元素小于
min
- 当前遍历到的元素大于
max
对于第一种情况,对答案没有影响,不需要考虑,直接跳过即可。
对于第二种情况,需要更新min
和maxProfit
变量。将min
更新为当前遍历到的元素,将maxProfit
更新为max
减更新后的min
即可。
对于第三种情况,需要更新max
,但由于答案只能由数组后面的元素减去前面的元素获得,所以min
也要一并更新。所以将max
与min
均更新为当前遍历到的元素即可。
最终答案就是maxProfit
变量
参考代码
public int maxProfit3(int[] prices){
// [7,1,5,3,6,4]
if(prices.length <= 1) return 0;
int maxProfit = 0;
int min = prices[prices.length - 1];
int max = prices[prices.length - 1];
for (int i = prices.length - 2; i >= 0; i--){
if (prices[i] < min)
min = prices[i];
else if (prices[i] > max)
{
max = prices[i];
min = prices[i];
}
if (maxProfit < max - min)
maxProfit = max - min;
}
return maxProfit;
}
解题方法四
/**
* 动态规划
*
* 记录【今天之前买入的最小值】
* 计算【今天之前最小值买入,今天卖出的获利】,也即【今天卖出的最大获利】
* 比较【每天的最大获利】,取最大值即可
*
* @param prices
* @return
*/
public int maxProfit4(int[] prices){
if(prices.length <= 1)
return 0;
int min = prices[0], max = 0;
for(int i = 1; i < prices.length; i++) {
max = Math.max(max, prices[i] - min);
min = Math.min(min, prices[i]);
}
return max;
}
微信关注
阅读剩余
版权声明:
作者:理想
链接:https://www.imyjs.cn/archives/593
文章版权归作者所有,未经允许请勿转载。
THE END