题目描述(简单难度)
给一个数组,看作每天股票的价格,然后某一天买入,某一天卖出,最大收益可以是多少。可以不操作,收入就是 0
。
解法一 暴力破解
先写个暴力的,看看对题目的理解对不对。用两个循环,外层循环表示买入时候的价格,内层循环表示卖出时候的价格,遍历所有的情况,期间更新最大的收益。
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++) {
maxProfit = Math.max(maxProfit, prices[j] - prices[i]);
}
}
return maxProfit;
}
"""
解题思路:设置两个循环,依次遍历,将结果保存到数组中,再从中挑选出最大值
"""
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_lis = [0]
for i in range(0,len(prices)):
for j in range(i+1,len(prices)):
if prices[j] > prices[i]:
max_lis.append(prices[j] - prices[i])
return max(max_lis)
解法二 双指针
这种数组优化,经常就是考虑双指针的方法,从而使得两层循环变成一层。思考一下怎么定义指针的含义。
用两个指针, buy 表示第几天买入,sell 表示第几天卖出
开始 buy,sell 都指向 0,表示不操作
3 6 7 2 9
^
b
^
s
sell 后移表示这天卖出,计算收益是 6 - 3 = 3
3 6 7 2 9
^ ^
b s
sell 后移表示这天卖出,计算收益是 7 - 3 = 4
3 6 7 2 9
^ ^
b s
sell 后移表示这天卖出,计算收益是 2 - 3 = -1
3 6 7 2 9 12
^ ^
b s
此外,如上图,当前 sell 指向的价格小于了我们买入的价格,所以我们要把 buy 指向当前 sell 才会获得更大的收益
原因很简单,收益的价格等于 prices[sell] - prices[buy],buy 指向 sell 会使得减数更小,
所以肯定要选更小的 buy
3 6 7 2 9 12
^
s
^
b
sell 后移表示这天卖出,计算收益是 9 - 2 = 7
这里也可以看出来减数从之前的 3 变成了 2,所以收益会更大
3 6 7 2 9 12
^ ^
b s
sell 后移表示这天卖出,计算收益是 12 - 2 = 10
3 6 7 2 9 12
^ ^
b s
然后在这些价格里选最大的就可以了。
代码的话就很好写了。
public int maxProfit(int[] prices) {
int maxProfit = 0;
int buy = 0;
int sell = 0;
for (; sell < prices.length; sell++) {
//当前价格更小了,更新 buy
if (prices[sell] < prices[buy]) {
buy = sell;
} else {
maxProfit = Math.max(maxProfit, prices[sell] - prices[buy]);
}
}
return maxProfit;
}
参考文献
1.https://zhuanlan.zhihu.com/p/76875330