leetcode笔记—关于买股票

原创 2016年06月01日 21:46:10

1.买卖股票的最佳时间(只能交易一次,买一次和卖一次)

当第i天买入,所获得的受益是第i+1天到第n天中的最大的股价与买入时的差

动态规划法。从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() == 0)
            return 0;
            
        int maxPrice = prices[prices.size()-1];//从最后一天的股价开始遍历,假如最后一天买入
        int ans = 0;
        for(int i = prices.size() - 1; i >= 0; i--)
        {
            maxPrice = max(maxPrice, prices[i]);//找出最大的股价
            ans = max(ans, maxPrice - prices[i]);
        }
        
        return ans;
    }
};

2.买卖股票的最佳时间(可以多次买卖,在买之前要先卖掉)

分析:贪心法。从前向后遍历数组,只要当天的价格高于前一天的价格,就算入收益

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //贪心法。从前向后遍历数组,只要当天的价格高于前一天的价格,就算入收益。
         if (prices.size() < 2) return 0;
        
        int maxProfit = 0;
        for (int i = 1; i < prices.size(); i++) {
            int diff = prices[i] - prices[i - 1];
            if (diff > 0) {
                maxProfit += diff;
            }
        }
        
        return maxProfit;
    }
};

3.用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。最多交易两次,手上最多只能持有一支股票,求最大收益。

动态规划法。以第i天为分界线,计算第i天之前进行一次交易的最大收益preProfit[i],和第i天之后进行一次交易的最大收益postProfit[i],最后遍历一遍,max{preProfit[i] + postProfit[i]} (0≤i≤n-1)就是最大收益。第i天之前和第i天之后进行一次的最大收益求法同Best Time to Buy and Sell Stock I。

class Solution {
public:
    //分两步走:分别计算之前交易和之后交易
    int maxProfit(vector<int>& prices) {
       if (prices.size() < 2) return 0;  
          
        int n = prices.size();  
        vector<int> preProfit(n);//之前交易
        vector<int> postProfit(n);  //之后交易
          
        int curMin = prices[0];  
        //之前交易
        for (int i = 1; i < n; i++) {  
            curMin = min(curMin, prices[i]);  //股票价格的最小值
            preProfit[i] = max(preProfit[i - 1], prices[i] - curMin);  
        }  
          
        int curMax = prices[n - 1];  
        //之后交易
        for (int i = n - 2; i >= 0; i--) {  
            curMax = max(curMax, prices[i]);  
            postProfit[i] = max(postProfit[i + 1], curMax - prices[i]);  
        }  
          
        int maxProfit = 0;  
        for (int i = 0; i < n; i++) {  
            maxProfit = max(maxProfit, preProfit[i] + postProfit[i]);  
        }  
          
        return  maxProfit;  
    }  
};

4.用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。最多交易k次,手上最多只能持有一支股票,求最大收益。

分析:特殊动态规划法。传统的动态规划我们会这样想,到第i天时进行j次交易的最大收益,要么等于到第i-1天时进行j次交易的最大收益(第i天价格低于第i-1天的价格),要么等于到第i-1天时进行j-1次交易,然后第i天进行一次交易(第i天价格高于第i-1天价格时)。于是得到动规方程如下(其中diff = prices[i] – prices[i – 1]):

profit[i][j] = max(profit[i – 1][j], profit[i – 1][j – 1] + diff)

看起来很有道理,但其实不对,为什么不对呢?因为diff是第i天和第i-1天的差额收益,如果第i-1天当天本身也有交易呢(也就是说第i-1天刚卖出了股票,然后又买入等到第i天再卖出),那么这两次交易就可以合为一次交易,这样profit[i – 1][j – 1] + diff实际上只进行了j-1次交易,而不是最多可以的j次,这样得到的最大收益就小了。

那么怎样计算第i天进行交易的情况的最大收益,才会避免少计算一次交易呢?我们用一个局部最优解和全局最优解表示到第i天进行j次的收益,这就是该动态规划的特殊之处。

用local[i][j]表示到达第i天时,最多进行j次交易的局部最优解;用global[i][j]表示到达第i天时,最多进行j次的全局最优解。它们二者的关系如下(其中diff = prices[i] – prices[i – 1]):

local[i][j] = max(global[i – 1][j – 1] , local[i – 1][j] + diff)
global[i][j] = max(global[i – 1][j], local[i][j])

local[i][j]和global[i][j]的区别是:local[i][j]意味着在第i天一定有交易(卖出)发生,当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即local[i][j]=local[i-1][j]+diff;当第i天的价格不高于第i-1天(即diff<=0)时,那么local[i][j]=global[i-1][j-1]+diff,而由于diff<=0,所以可写成local[i][j]=global[i-1][j-1]。global[i][j]就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:如果第i天没有交易(卖出),那么global[i][j]=global[i-1][j];如果第i天有交易(卖出),那么global[i][j]=local[i][j]。

参考:http://www.cnblogs.com/grandyang/p/4295761.html

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if (prices.size() < 2) return 0;
        if (k >= prices.size()) return maxProfit2(prices);
        
        vector<int> local(k+1);
        vector<int> global(k + 1);
        
        //i表示天数
        for (int i = 1; i < prices.size() ; i++) {
            int diff = prices[i] - prices[i - 1];
            
            for (int j = k; j > 0; j--) {
                local[j] =max(global[j - 1], local[j] + diff);
                global[j] =max(global[j], local[j]);
                /////???????????为什么
            }
        }
        
        return global[k];
    }
    
    //交易次数不限制
   int maxProfit2(vector<int> prices) {
        int maxProfit = 0;
        for (int i = 1; i < prices.size(); i++) {
            if (prices[i] > prices[i - 1]) {
                //只要当天股票价格比前一天大就为收益
                maxProfit += prices[i] - prices[i - 1];
            }
        }
        
        return maxProfit;
   }
};


5.Best Time to Buy and Sell Stock with Cooldown

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int buy = INT_MIN, pre_buy = 0, sell = 0, pre_sell = 0;
        for (int price : prices) {
            pre_buy = buy;
            buy = max(pre_sell - price, pre_buy);
            pre_sell = sell;
            sell = max(pre_buy + price, pre_sell);
        }
        return sell;
    }
};



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

LeetCode—买卖股票的最好时机

1.Best Time to Buy and Sell Stock Description: Say you have an array for which the ith element is ...

Leetcode 122. Best Time to Buy and Sell Stock II 股票买卖2 解题报告

1 解题思想首先请看下第一个问题: Leetcode 121. Best Time to Buy and Sell Stock 股票买卖 解题报告 题目给定的数组还是一样的含义,依旧代表股票的价...
  • MebiuW
  • MebiuW
  • 2016年10月09日 10:41
  • 411

Leetcode 123 Best Time to Buy and Sell Stock III 至多两次买卖股票最大收益

假设你有一个数组,里面记录的是每一天的股票的价格。 设计一个算法来计算最大收益。你至多可以完成两次交易...

Leetcode 122 Best Time to Buy and Sell Stock II 不限次数买卖股票最大收益

假设你有一个数组,里面记录的是每一天的股票的价格。设计一个算法来计算最大收益。你可以完成任意次数的交易(即,买买股票多次)。但是你不能同时进行多次交易(即,在你买入股票之前必须卖掉手里的股票)。...

LeetCode 309. Best Time to Buy and Sell Stock with Cooldown(股票交易)

原题网址:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ Say you have an ...
  • jmspan
  • jmspan
  • 2016年04月20日 13:34
  • 456

LeetCode OJ 之 Best Time to Buy and Sell Stock III (买卖股票的最佳时间 - 三)

题目: Say you have an array for which the ith element is the price of a given stock on day i. Desig...

[LeetCode]Buy and Sell Stocks 买卖股票问题

LeetCode上关于买卖股票的问题一共有五道,题号分别为121,122,123,188,309。 此类问题的基本描述即给出一个序列prices[],prices[i]代表第i天股票的价格。 如果当天...

[LeetCode]121. Best Time to Buy and Sell Stock(求近期股票能获得的最大利润)

121. Best Time to Buy and Sell Stock原题链接 Say you have an array for which the ith element is the pri...

Leetcode 123. Best Time to Buy and Sell Stock III 股票买卖3 解题报告

1 解题思想嗯,是的,已经第三题了,数组代表什么我不想再复述一次,自己看: Leetcode 122. Best Time to Buy and Sell Stock II 股票买卖2 解题报告 ...
  • MebiuW
  • MebiuW
  • 2016年10月09日 11:14
  • 900

LeetCode 123. Best Time to Buy and Sell Stock III(股票买卖)

原题网址:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ Say you have an array for ...
  • jmspan
  • jmspan
  • 2016年05月24日 00:37
  • 411
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:leetcode笔记—关于买股票
举报原因:
原因补充:

(最多只允许输入30个字)