给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
法一 :暴力
两边循环找最大差值
时间复杂度O(n^2)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans = 0;
for(int i = 0;i<prices.size();i++)
{
for(int j = i+1;j<prices.size();j++)
{
ans = max(ans,prices[j]-prices[i]);
}
}
return ans;
}
};
法二 :一次遍历
class Solution {
public:
int maxProfit(vector<int>& prices) {
int minval = 1e9;
int maxprofit = 0;
int maxval = 1e-9;
for(int i = 0;i<(prices.size();i++)
{
maxprofit = max(maxprofit,prices[i] - minval);//最大时卖出
minval = min(minval,prices[i]);//最小时买入
}
return maxprofit;
}
};
时间复杂度O(n)
法三:单调栈
当需要高效率查询某个位置的左右两次的它大或者小的数字的位置,则可以用单调栈。
入栈元素要大于栈顶元素,否则循环弹栈
每次弹出时,我们将其与买入时做差,维护其最大值
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans;
vector <int>st;
prices.push_back(-1);
for(int i = 0;i<prices.size();i++)
{
while(!st.empty() && st.back() > prices[i]) //维护单调栈
{
ans = max(ans,st.back()-st.front()); //记录最大值
st.pop_back();
}
st.push_back(prices[i]);
}
return ans;
}
};