121. Best Time to Buy and Sell Stock
题目描述和难度
- 题目描述:
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4] 输出: 5 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1] 输出: 0 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
- 题目难度:简单。
- 英文网址:121. Best Time to Buy and Sell Stock 。
- 中文网址:121. 买卖股票的最佳时机 。
思路分析
求解关键:在最多只允许交易一次的情况下,要求出一段时间内的最大利润,我们只需找到股价最低的一天买进,然后在股价最高的一天卖出即可(并且要满足先买后卖的规则)。因此我们可以在遍历的时候记录之前遍历的最小值,用当前值减去这个最小值,从中取最大。
我们写出了参考解答 1 以后,发现下面这两行代码第 1 行求最大值,第 2 行求最小值,于是我们想能不能把它们的结构统一起来。
maxProfit = Integer.max(maxProfit, prices[i] - preMinimum);
preMinimum = Integer.min(preMinimum, prices[i]);
我们要求利润最大化,因此,我们的方向是把 min
改成 max
,很简单,取个负号就行了。其含义也很直观, 0 - price
就表示当前以及之前假如我执行了买操作我的利润,我肯定是还是希望我的利润越来越大。
而我如果执行了卖操作,这个值是和买操作相关的,很容易我们就写出了下面的两行代码,并且,这个操作可以从索引为 0 开始。接下来设置初始值就比较关键了,如果我是买操作,最差我一直卖,所以初始值是整数的最小值;如果我是卖操作,最差我不赚钱,所以下界就是 0。
// 在当前以及之前如果执行了买操作,能够得到的利润的最大值
buy = Integer.max(buy, -price);
// 在当前以及之前如果执行了卖操作,能够得到的利润的最大值
sell = Integer.max(sell, buy + price);
完整代码就是:
int buy = Integer.MIN_VALUE;
int sell = 0;
for (int price : prices) {
buy = Integer.max(buy, -price);
sell = Integer.max(sell, buy + price);
}
return sell;
- 可以用这个思路,解 LeetCode 第 123 题。
参考解答
参考解答1
public class Solution {
/**
* 在遍历的时候,记录之前遍历到的元素的最小值
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int len = prices.length;
if (len == 0) {
return 0;
}
int maxProfit = 0;
// 之前遍历到的所有元素的最小值
int preMinimum = prices[0];
// 从索引为 1 的元素开始
for (int i = 1; i < len; i++) {
// 当前值减去之前遍历到的元素的最小值,从中取出最大,即为所求
maxProfit = Integer.max(maxProfit, prices[i] - preMinimum);
preMinimum = Integer.min(preMinimum, prices[i]);
}
return maxProfit;
}
}
参考解答2
public class Solution2 {
public int maxProfit(int[] prices) {
int buy = Integer.MIN_VALUE;
int sell = 0;
for (int price : prices) {
buy = Integer.max(buy, -price);
sell = Integer.max(sell, buy + price);
}
return sell;
}
public static void main(String[] args) {
int[] prices = {7, 1, 5, 3, 6, 4};
Solution2 solution2 = new Solution2();
int maxProfit = solution2.maxProfit(prices);
System.out.println(maxProfit);
}
}
本篇文章的地址为 https://liweiwei1419.github.io/leetcode-solution/leetcode-0121-best-time-to-buy-and-sell-stock ,如果我的题解有错误,或者您有更好的解法,欢迎您告诉我 liweiwei1419@gmail.com 。