码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 笔记23 Best Time to Buy and Sell Stock III

时间:2015-02-18 10:39:18      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

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.

现在A股涨这么好,要是股票都提前知道价格就好了(@_@)

首先,考虑如果至多只能做一次交易呢?

那很简单嘛,大家都知道O(n^2)的方法,两个循环,确定(buyDay, sellDay)取到最大的profit。

怎么优化呢?

其实如果只做一次交易,那么遍历一次数组就可以了。

从0开始,到最后一天。在遍历到第i天的时候,我们用prices[i]减去当前所知道的最小的price,看一下是否比当前max profit大,如果是,就更新max profit。

我们不用关心后面的更小值哦,因为它们不影响当前profit,毕竟你只有先买了才能卖。

技术分享

同理也可以从最后一天开始往前遍历,这时候我们不记录当前所知道的最小price,而是最大值,用最大值减去prices[i]来和max profit比较。代码在这下面。

public int maxProfit(int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int maxProfit = 0;
        int minIndex = 0;
        for(int i = 1; i < prices.length; i++) {
            if (prices[i] < prices[minIndex]) {
                minIndex = i;
            }
            if (prices[i] - prices[minIndex] > maxProfit) {
                maxProfit = prices[i] - prices[minIndex];
            }
        }
        return maxProfit;
    }

然后我们来看如何计算”买卖两次“的最大profit。

因为有了买卖一次的交易算法,我们比较容易去这样想。把整个个prices数组分成两部分,计算前一部分买卖一次的最大值,计算后一部分买卖的最大值,然后求和。然后从0到length重复该操作,求出整个数组上买卖两次的最大值。

不过这样复杂度变成了O(n^2)。

有没有更好的方法呢?

其实这样想,我们在计算买卖一次的遍历过程中,已经有这样的信息了,那就是,在第0天到第i天,买卖一次能得到的最大profit,假设是forward[i]。同理,如果从后面往前遍历的过程中,我们拿到从第i天到最后一天,买卖一次能得到的最大profit,假设是backward[i]。

于是我们最后一步要求的不就是max(forward[i] + backward[i] for i = 0... length)嘛?这样O(n)就能求出来了。

代码如下:

public int maxProfit(int[] prices) {
        int[] maxProfit = new int[prices.length];
        if (prices.length <= 1) {
            return 0;
        }
        //forward
        int minIndex = 0;
        for(int i = 1; i < prices.length; i++) {
            if (prices[i] < prices[minIndex]) {
                minIndex = i;
            }
            maxProfit[i] = Math.max(maxProfit[i], prices[i] - prices[minIndex]);
        }
        //backward
        int maxIndex = prices.length - 1;
        int ret = 0;
        int iMax = 0;
        for(int i = prices.length - 2; i >= 0; i--) {
            if (prices[i] > prices[maxIndex]) {
                maxIndex = i;
            }
            iMax = Math.max(iMax, prices[maxIndex] - prices[i]);
            ret = Math.max(ret, iMax + maxProfit[i]);
        }
        return ret;
    }

注意我们没有使用backward[i],因为第二次遍历直接就能得到max profit了。

 

LeetCode 笔记23 Best Time to Buy and Sell Stock III

标签:

原文地址:http://www.cnblogs.com/lichen782/p/4295658.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!