题目链接
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
注意点
并不是单纯地找最小值之后的最大值就可以;该题的本质应该是求某个数与其右边最大数的差值,结果是这些差值中的最大值。
解法
解法1:单调栈
利用单调栈可以高效率查询某个位置左右两侧比他大(或小)的数的位置。
单调栈的维护策略是:
1.当栈为空或者当前元素大于等于栈顶元素时,入栈。
2.当栈不为空,且当前元素小于栈顶元素的时候,循环弹出栈顶元素,直到当前元素还是大于栈顶元素。
计算栈顶元素和栈低元素的差值,维护最大的差值
在代码实现上,因为要利用栈低元素,所以我用了双端队列实现,效率不是特别高。
执行用时 :
8 ms
, 在所有 C++ 提交中击败了
86.25%
的用户
内存消耗 :
13.4 MB
, 在所有 C++ 提交中击败了
6.56%
的用户
class Solution {
public:
int maxProfit(vector<int>& prices) {
deque<int> dq;
int max=0;
int i=0;
while(i<prices.size()){
while(!dq.empty() && prices[i]<dq.back()){
dq.pop_back();
}
dq.emplace_back(prices[i]);
if(max<prices[i]-dq.front()){
max=prices[i]-dq.front();
}
i++;
}
return max;
}
};
解法2:维护最小值法
单调栈的做法要用到o(n)的空间,空间利用率不高。
我们可以直接对当前数组维护一个最小值,并计算当前元素和最小值之差来更新差值,若当前元素比最小值更小,则更新最小值。
执行用时 :
8 ms
, 在所有 C++ 提交中击败了
86.25%
的用户
内存消耗 :
12.9 MB
, 在所有 C++ 提交中击败了
6.56%
的用户
class Solution {
public:
int maxProfit(vector<int>& prices) {
int minprice = INT_MAX, maxprofit = 0;
for(const auto &it : prices)
{
maxprofit = max(maxprofit, it - minprice);
minprice = min(minprice, it); // 后面的踩可以使用当前的最小的
}
return maxprofit;
}
};
咦……怎么空间还是这么大……
遇到问题
单调栈如何维护以及使用场景
小结
单调栈