leetcode-Best Time to Buy and Sell Stock

Best Time to Buy and Sell Stock

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        int min = prices[0];
        int res=0;
        for(int i=1;i<prices.size();i++){
            if(prices[i]<min) {
                min = prices[i];
            }
            else{
                if(res<prices[i]-min) res =prices[i]-min;
            }
        }
        return res;
    }
};

其实也算是DP,每次的结果和前一次的结果比较


Best Time to Buy and Sell Stock II


class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        int profit = 0;
        int min = prices[0];
        int max = prices[0];
        for(int i=1;i<prices.size();i++){
            if(prices[i]<prices[i-1]){
                profit+=max-min;
                min = prices[i];
                max = prices[i];
            }
            else{
                max = max>prices[i]?max:prices[i];
            }
        }
        profit+=max-min;
        return profit;
    }
};

每次下跌前将之前的股票卖出以获得最高的总额


Best Time to Buy and Sell Stock III

DP1

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        vector<int> profit1(prices.size(), 0);
        vector<int> profit2(prices.size(), 0);
        int min = prices[0];
        int maxp = 0;
        for(int i=1;i<prices.size();i++){
            if(prices[i]<min){
                min = prices[i];
                profit1[i] = maxp;
            }
            else {
                if(prices[i]-min>maxp) maxp = prices[i]-min;
                profit1[i] = maxp;
            }
        }
        for(int i=1;i<prices.size();i++){
            int temp = 0;
            for(int j=1;j<i;j++){
                temp = max(temp, prices[i]-prices[j]+profit1[j]);
            }
            profit2[i] = max(temp, profit1[i]);
        }
        int profit = 0;
        for(int i=0;i<profit1.size();i++) cout<<profit1[i];
        cout<<endl;
        for(int i=0;i<prices.size();i++){
            if(profit2[i]>profit) profit = profit2[i];
            cout<<profit2[i];
        }
        cout<<endl;
        return profit;
    }
};

Simplest DP concept. For everyday, there are 3 choices: buy nothing(0) / buy and sell one stock/ buy and sell two stocks. Buy and sell one stock can be calculated by one pass as in series I. Buy and sell two stocks the profit and be divided into the best one stock profit in Day j and best profit between Day j and Day i. i.e. prices[i]-prices[j]+profit1[j] The best profit must comes from a day with minimum price, then that day's profit1 cannot exceed previous day's profit. Here profit1 should be the best profit from 1 stock till now.
Then profit2[i] is max(max(prices[i]-prices[j]+profit1[j]), profit1[i]).

DP2
Consider to improve DP1, find that max(prices[i]-prices[j]+profit1[j]) can be simplified to prices[1]+max(profit1[j]-prices[j]), thus we have no need to calculate profit1[j]-prices[j] every i, just calculate max of it for every j once. O(n2)->O(n)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        vector<int> profit1(prices.size(), 0);
        vector<int> profit2(prices.size(), 0);
        int min = prices[0];
        int maxp = 0;
        for(int i=1;i<prices.size();i++){
            if(prices[i]<min){
                min = prices[i];
                profit1[i] = maxp;
            }
            else {
                if(prices[i]-min>maxp) maxp = prices[i]-min;
                profit1[i] = maxp;
            }
        }
        vector<int> maxp1(prices.size(),0);
        maxp1[0]=profit1[0]-prices[0];
        for(int i=1;i<maxp1.size();i++){
            maxp1[i] = max(maxp1[i-1], profit1[i]-prices[i]);
        }
        //for(int i=0;i<profit1.size();i++) cout<<profit1[i];
       // cout<<endl;
        //for(int i=0;i<profit1.size();i++) cout<<maxp1[i];
        //cout<<endl;
        for(int i=1;i<prices.size();i++){
            profit2[i] = max(maxp1[i-1]+prices[i], profit1[i]);
        }
        int profit = 0;
        for(int i=0;i<prices.size();i++){
            if(profit2[i]>profit) profit = profit2[i];
            //cout<<profit2[i];
        }
        //cout<<endl;
        return profit;
    }
};

DP3
Find that profit2 only depends on maxp and profit1 before it, so can improve O(n) space to O(1).

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        int profit1=0;
        int maxp1=-prices[0];
        int profit2=0;
        int min = prices[0];
        for(int i=1;i<prices.size();i++){
            if(prices[i]<min){
                min = prices[i];
            }
            else {
                if(prices[i]-min>profit1) profit1 = prices[i]-min;
            }
            profit2 = max(profit2, profit1);
            profit2 = max(profit2, maxp1+prices[i]);
            maxp1=max(maxp1, profit1-prices[i]);
        }
        return profit2;
    }
};

还有一种方法是以第i天为中线,计算0-i的股票最大收益+i-end的股票最大收益。
一开始认为对每个i都需要计算0-i和i-end需要O(n2)time,但是实际上只需要对每一天j计算股票0-j的收益,和j-end的收益,计算好之后再以i分隔,时间为O(n)。


Best Time to Buy and Sell Stock IV

依照之前的DP,复杂度为O(kn),k过大的情况下会TLE

  1. 单独考虑K大的情况,K>n/2则所有增益都能获得
  2. 不考虑每天的买入买出只考虑上涨的pair,之后有空再补

Best Time to Buy and Sell Stock with Cooldown

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()<=1) return 0;
        vector<int> buy(prices.size(), 0);
        vector<int> sell(prices.size(), 0);
        buy[0] = -prices[0];
        buy[1] = max(-prices[1], -prices[0]);
        sell[0] = 0;
        sell[1] = prices[1]-prices[0]>0?prices[1]-prices[0]:0;
        for(int i=2;i<prices.size();i++){
            buy[i] = max(buy[i-1], sell[i-2] - prices[i]);
            sell[i] = max(sell[i-1], buy[i-1]+prices[i]);
        }
        return sell[sell.size()-1];
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容