这道题绝对有中等难度了。可以用状态机dp来做,因为只和前一天的两个状态有关,所以可以状态压缩,压缩到常量级别。最后返回的是最后一天不持有股票的情况。因为最后一天买了就卖不出去,所以肯定不会买,如果之前有,那么最后一天必须要卖掉,所以最后一天肯定无股票。
贪心的应该是想不到的,只要当前这一天比前一天大,就让结果加上当前减去前一天的值
class Solution {
public:
int maxProfit(vector<int>& prices) {
//只要后一天的比前一天的高就卖出
//加入123,这样的,那么第一天买,第二天卖,赚了1元,然后再买再卖,赚了1元,一共2元。
//和第一天买第三天卖结果一样
//int res = 0;
// for(int i = 1;i < prices.size(); ++i){
// if(prices[i] > prices[i-1]){
// res += (prices[i]-prices[i-1]);
// }
// }
//状态机dp,dp[i][0]和dp[i][1]的意思是第i天持有或者不持有股票手上的钱,注意是利润初始化,如果第一天就持有
// vector<vector<int>> dp(prices.size(),vector<int>(2));
// dp[0][0] = 0;
// dp[0][1] = -prices[0];
// //状态转移方程是如果今天是没有的,那么有可能前一天是有的然后今天卖掉的,也有可能前一天就是没有的
// //如果今天是有的,可能前一天就是有的,或者前一天没有今天刚买
// for(int i = 1; i < prices.size(); ++i){
// dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]);
// dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
// }
// //最后一定要不持有股票收益才最大,不买最后一天,或者最后一天卖掉
// return dp[prices.size()-1][0];
//状压dp,当前的状态只和前一天的两个状态有关
int nhave = 0, have = -prices[0];
for(int i = 1; i < prices.size(); ++i){
int nhave1 = max(nhave,have+prices[i]);
int have1 = max(have,nhave-prices[i]);
nhave = nhave1;
have = have1;
}
return nhave;
}
};
贪心做做得了,用一个minn记录在碰到比自己大的之前的最小股票价格,碰到比自己大的,就让res加上两者之差,然后更新minn。如果碰不到比自己大的,证明都是小于等于自己的,就更新minn,毕竟minn越小赚得越多。
class Solution {
public:
int maxProfit(vector<int>& prices) {
//贪心算法or状态机dp
//可以卖了之后马上买当天
//所以345,买3,然后4那天卖掉,然后买4,5那天卖掉和买3,5那天卖掉的结果一样
//记录一个值,碰到比自己小的就更新,碰到比自己大的就买掉,然后买它,用当天的值来更新
if(prices.size() == 0) return 0;
int res = 0;
int minn = prices[0];
for(int i = 1; i < prices.size();++i){
if(prices[i]>minn) {
res+=prices[i]-minn;
minn = prices[i];
}
minn = prices[i];
}
return res;
}
};