LeetCode121—Best Time to Buy and Sell Stock

LeetCode121—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.

即一个数组存放第i天股票的价格,然后买卖一次股票使得利益最大。

分析1

题意理解一下即在数组中找两个差值最大数,再进一步说就是找到一个相对最小值 prices[i] 和相对最大值 p[j] ,且满足 i<j ,这里说相对最小和最大原因就在于股票必须先买后卖时间顺序需要遵守。

那么就循环一次, p[i] 就可以理解成当前卖出最大,而当前最小用一个变量来维护即可。

代码1

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(0==prices.size())
            return 0;
        int curMin = prices[0];//当前最低买入价格
        int curMax=0;//prices[0]-prices[0]//当前最大利益
        for (int i = 1; i < prices.size(); i++)
        {
            if (curMin>prices[i])
                curMin = prices[i];
            if (prices[i] - curMin > curMax)
                curMax = prices[i] - curMin;
        }
        return curMax;
    }
};

分析2

如果说上述解法是可以自己想出来说的野路子,那下面这个动态规划的解法就比较规范了吧。
参考:http://blog.csdn.net/linhuanmars/article/details/23162793
这里用到全局最优global和局部最优local构建动归方程:
假设令:
diff=prices[i+1]prices[i](1)
则局部最优 local[i] 表示在第i天卖出的最大利益:
local[i+1]=max(local[i]+diff,0)(2)
而全局最优 global[i] 表示前i天获得的最大利益:
global[i+1]=max(local[i+1],global[i])(3)

根据上述三个方程容易写出代码:

代码2

class Solution{
public:
    int maxProfit(vector<int>& prices) {
        if(0==prices.size())
            return 0;
        vector<int>local(prices.size());//局部最优
        vector<int>global(prices.size());//全局最优
        for (int i = 0; i < prices.size()-1; i++)
        {
            int tmp = prices[i + 1] - prices[i];
            local[i + 1] =max(0,tmp+local[i]);
            global[i + 1] = max(global[i], local[i + 1]);
        }
        return global[prices.size() - 1];
    }
};

分析3

接分析2的内容,还是同样的动归方程,这里把空间复杂度降到O(1),因此每次更新需要上一次的数据,用一个变量保存当前数据即可,上一次的数据用过以后就可以覆盖了。例如计算第i+1次的数据时,第i次的数据用过(等式右边),就可以被覆盖了(等式左边赋给第i+1次数据)

代码3

class Solution{
public:
    int maxProfit(vector<int>& prices) {
        if (0 == prices.size())
            return 0;
        int local = 0;// 局部最优
        int global = 0;//全局最优
        for (int i = 0; i < prices.size() - 1; i++)
        {
            int diff = prices[i + 1] - prices[i];
            local = max(0, diff + local);
            global = max(global, local);
        }
        return global;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值