题目描述:
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例 1:
示例2:
提示:
1.暴力法 代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = (int)prices.size(), maxr = 0;
for (int i = 0; i < n; ++i){
for (int j = i + 1; j < n; ++j) {
maxr = max(maxr, prices[j] - prices[i]);
}
}
return maxr;
}
};
直接双层for循环,不会超时。
2.暴力法优化 代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size();
if(n==0||n==1)return 0;
int m_max[50000],m_min[50000];
memset(m_max,0,sizeof(m_max));
memset(m_min,0,sizeof(m_min));
for(int i=0;i<n;i++){
if(m_min[prices[i]]==0)m_min[prices[i]]=i+1;//m_min记录每个数字最早出现的位置,+1防止误把位置0当作没有记录
m_max[prices[i]]=i+1; //m_max记录每个数字最后出现的位置
}
sort(prices.begin(),prices.end()); //从小到大排序
int max=0;
for(int i=0;i<n-1;i++){
if(i!=0&&prices[i]==prices[i-1])continue;
else{
for(int j=n-1;j>=i+1;j--){
if(j!=n-1&&prices[j]==prices[j+1])continue;
if(prices[j]-prices[i]<=max)break;
if(m_max[prices[j]]>m_min[prices[i]]){
if(prices[j]-prices[i]>max)max=prices[j]-prices[i];
}
}
}
}
return max;
}
};
按照price排序,并用两个数组**(不可以用map,map比数组慢会超时**)记录各个price最早和最晚出现的位置下标,从两头开始查找,若高price的下标大于低price的下标,计算并更新max;
因为已经排序,每次循环时,若当前数字和上一个数字相等则跳过,不必再判断,跳过直接查看下一个数,节省时间。
3.一次遍历/动态规划 代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size(),maxr=0,minprice=0;
if(n==0||n==1)return 0;
minprice=prices[0];
for (int i = 0; i < n; ++i){
maxr=max(maxr,prices[i]-minprice); //最低点买入,当天抛售能有多少利润
minprice=min(minprice,prices[i]);//更新当前查找段的最低价格
}
return maxr;
}
};
转换思路,要求最大利润,只需每天都计算如果在最低点买入今天抛售可以获得多少利润,比较记录最大值。