LeetCode:Best Time to Buy and Sell Stock(买卖股票)系列

来源:互联网 发布:2017淘宝双11活动规则 编辑:程序博客网 时间:2024/05/18 03:15

121. Best Time to Buy and Sell Stock


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

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Example 1:
Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0

In this case, no transaction is done, i.e. max profit = 0.


监督最低价,更新最大利润(时刻与当前最大利润比较,取最大值)。


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

122. Best Time to Buy and Sell Stock II


终于 明白什么叫贪心算法了,原来只要有收益就加入,不要担心其他的,因为都很自然符合。


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

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).


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

123. 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.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).


这个题目会做,是因为做过,但是写的时候还遗漏了,在维护两个数组的时候,一定要记得是利润最大值,要比较更新取最大。但是后面发现本题可以解得更加简单。

风口的猪-中国牛市(小米2016校招)
http://blog.csdn.net/bestzem/article/details/51867015


class Solution {public:    int maxProfit(vector<int>& prices) {        if(prices.empty()||prices.size()==1)    return 0;        int len=prices.size();        vector<int> left(len),right(len);        left[0]=right[len-1]=0;        int mine=prices[0];        for(int i=1;i<len;++i)//第一次最大        {            if(prices[i]>mine)            {                left[i]=max(prices[i]-mine,left[i-1]);            }            else            {                left[i]=left[i-1];                mine=prices[i];            }        }        int maxe=prices[len-1];        for(int i=len-2;i>=0;--i)//第二次最大        {            if(prices[i]<maxe)            {                right[i]=max(maxe-prices[i],right[i-1]);            }            else            {                right[i]=right[i-1];                maxe=prices[i];            }        }        int res=0;        for(int i=0;i<len;++i)        {            res=max(res,left[i]+right[i]);        }        return res;    }};

更新方程解法:
这个应该比下一题的好理解的多了。从后往前将局部最优解和全局最优解求出。


class Solution {public:    int maxProfit(vector<int>& prices) {        if(prices.empty()||prices.size()==1)    return 0;        int len=prices.size();        int global[3]{},local[3]{};        for(int i=1;i<len;++i)        {            int diff=prices[i]-prices[i-1];            for(int j=2;j>0;--j)            {                local[j]=max(global[j-1],local[j]+diff);                global[j]=max(global[j],local[j]);            }        }        return global[2];    }};

188. Best Time to Buy and Sell Stock IV


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

Design an algorithm to find the maximum profit. You may complete at most k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).


此题甚难,待研究,注意要排除k过大情况。

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]。


class Solution {public:    int solveMaxProfit(vector<int> &prices) {//k过大时等于贪心解法        int res = 0;        for (int i = 1; i < prices.size(); ++i)         {            if (prices[i] - prices[i - 1] > 0)             {                res += prices[i] - prices[i - 1];            }        }        return res;    }    int maxProfit(int k, vector<int>& prices) {        if(prices.empty()||prices.size()==1)  return 0;        int len=prices.size(),w{k+1};        if(k>len)   return solveMaxProfit(prices);        vector<int> global(len*w,0),local(len*w,0);        for(int i=1;i<len;++i)        {              int diff = prices[i]-prices[i-1];            for(int j=1;j<w;++j)             {                  local[i*w+j] = max(global[(i-1)*w+j-1]+(diff>0?diff:0), local[(i-1)*w+j]+diff);                  global[i*w+j] = max(local[i*w+j],global[(i-1)*w+j]);              }          }          return global.back();      }};

数组降为一维解法:

针对IV的描述
http://blog.csdn.net/linhuanmars/article/details/23236995

class Solution {public:    int solveMaxProfit(vector<int> &prices) {//k过大时等于贪心解法        int res = 0;        for (int i = 1; i < prices.size(); ++i)         {            if (prices[i] - prices[i - 1] > 0)             {                res += prices[i] - prices[i - 1];            }        }        return res;    }    int maxProfit(int k, vector<int>& prices) {        if(prices.empty()||prices.size()==1)  return 0;        int len=prices.size(),w{k+1};        if(k>len)   return solveMaxProfit(prices);        vector<int> global(w,0),local(w,0);        for(int i=1;i<len;++i)        {            int diff = prices[i]-prices[i-1];            for(int j=k;j>0;--j)            {                local[j]=max(local[j]+diff,global[j-1]);//+(diff>0?diff:0)                global[j]=max(global[j],local[j]);            }        }        return global.back();     }};

Reference:
四个题描述
http://liangjiabin.com/blog/2015/04/leetcode-best-time-to-buy-and-sell-stock.html


2016、8、1更


309. Best Time to Buy and Sell Stock with Cooldown


这是别人家的代码,维护四个变量,其中主要有支出和收入。

Reference:
https://discuss.leetcode.com/topic/30421/share-my-thinking-process/2


class Solution {public:    int maxProfit(vector<int>& prices) {        //INT_MIN=-2147483648,        int buy(INT_MIN), sell(0), prev_sell(0), prev_buy;        for (const int &price : prices) {            prev_buy = buy;            buy = max(prev_sell - price, buy);//支出            prev_sell = sell;            sell = max(prev_buy + price, sell);//收入        }        return sell;    }};/*              6   1   3   2   4   7*prev_buy  INT_MIN  -6  -1  -1  -1  -1  *buy            -6  -1  -1  -1  -1  -1*prev_sell      0   0   0   2   2   3*sell           0   0   2   2   3   6*/
0 0