121. Best Time to Buy and Sell Stock

来源:互联网 发布:linux卸载jdk 编辑:程序博客网 时间:2024/05/22 00:22

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: 5max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)

两者的算法时间复杂度都是O(n),动态规划的空间复杂度是n,kadane的空间复杂度是1

1、动态规划

思路:存储第i天的最大抛售值和最小股票值。对于第i+1天,

(1)如果当天的股票值大于之前的最小股票值,则:不更新最小股票值,比较当前值-最小股票值与第i-1天的抛售值的大者;

(2)如果当天的股票值小于之前的最小股票值,更新最小股票值,不更新最大抛售值,不能用之前的数减现在的最小值

输出给定天的股票抛售值。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //以动态规划的思想,存储当前的最小值,和最大抛售值,算法复杂度为O(n)
        int n=prices.size();
        if(prices.size()<=1) return 0;
        vector<int> minstack(n,0);
        vector<int> transaction(n,0);
        minstack[0]=prices[0];
        transaction[0]=0;
        for(int i=1;i<n;i++)
        {
            if(prices[i]<minstack[i-1]) {//当当前值比前面的最小值小时,更新最小值,不更新最大抛售值
                minstack[i]=prices[i];//当前最小值
                transaction[i]=transaction[i-1];
            }
            else//当当前值比前面的最小值大时,不更新最小值,比较更新最大抛售值
            {
                minstack[i]=minstack[i-1];
                transaction[i]=transaction[i-1]>(prices[i]-minstack[i])?transaction[i-1]:prices[i]-minstack[i];
            }
        }
        return transaction[n-1];
        
    }
};

2、转换为最大连续子数列和

[7, 1, 5, 3, 6, 4]
每天的股票值可以转换成[0,-6,4,-2,3,-2],表示相邻天买入卖出的股票抛售值。这个序列可以转换为求最大连续子数列和的问题。下面列出kadane算法解决最大连续子数列和:
  • 遍历该数组, 在遍历过程中, 将遍历到的元素依次累加起来, 当累加结果小于或等于0时, 从下一个元素开始,重新开始累加。
  • 累加过程中, 要用一个变量(max_so_far)记录所获得过的最大值
  • 一次遍历之后, 变量 max_so_far 中存储的即为最大子片段的和值。
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //kadane算法,转换为最大连续子数列和的问题
        int curmax=0,summax=0;
        for(int i=1;i<prices.size();i++)
        {
            curmax=max(0,curmax+prices[i]-prices[i-1]);
            summax=max(summax,curmax);
        }
        return summax;
    }
};


1 0