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

二、分析和解答
买卖股票,这一次是指可以多次买入和卖出,不过必须先买入再卖出,不能同时进行这两个操作!
1、我的做法:这个是基于上一题的,后面的数得比前面的数大才行。上一题是找到差值最大的两个数即为最大利润!而这次由于可以操作多次,因此需要把所有的具有最大的正利润的值都找出来,其实就是找所有递增的子数组!然后子数组的最后一位的值减去第一位的值就是这段时间的最大利润,把所有的子数组的该值求和即可!代码如下:

public int maxProfit(int[] prices) {
        if(prices.length == 0)
            return 0;
        int low = 0,high = 0;
        int profit = 0;
        for(int i=1;i<prices.length;i++){
            if(prices[i] <= prices[i-1]){//从大变小
                high = i - 1;//为该数组设置上限
                //求当前子数组的最大利润
                profit += prices[high] - prices[low];
                //为下一个子数组设置下限
                low = i;
            }
        }
        //处理最后的情况!
        if(prices.length >= 2 && prices[prices.length-1] > prices[prices.length-2]){
            high = prices.length-1;
            profit += prices[high] - prices[low];
        }
        return profit;
    }

找子数组,一般也会考虑快慢指针!像冒泡排序一样,两两值之间进行比较,若是从小到大,继续;若从大变小,说明这是一个关键点,要重新设置相关数组的上界或下界。
我已开始比较的是i值和i+1的值,但这样会导致最后的值不能处理。然后又比较i和i-1的值,发现还是不能完全处理!例如;[7,1,5,6,3,4],当arr[ i ] = 3的时候,low = 4,之后3和4的值不能计算了。。。。。所以无论如何都要进行最后一步的补充运算

2、然后我对代码进行了优化:

public int maxProfit(int[] prices) {
        if(prices.length == 0)
            return 0;
        int low = 0,high = 0;
        int profit = 0;
        for(int i=1;i<prices.length;i++){
            //注意:这里必须有等于号,案例:[2,1]
            if(prices[i] <= prices[i-1] && low <= high){
                profit += prices[high] - prices[low];
                low = i;//进入新的子数组下限
            }
             high = i;//high每次随i变化
        }
        if(low < high){//最后一步的补充运算
            profit += prices[high] - prices[low];
        }
        return profit;
    }

其实最后的那个if(low < high)的判断也可以去掉,直接像下面的那个进行加减即可。因为low和high只可能相同,或者high在low的前面,代码里面赋值可以看到。
关键点在于大值向小值变化的那两个数,这时候前面的递增子数组肯定就结束了,最少可能是一个元素。求的这个子数组的最大利润后,把low指针放到新的子数组的那个位置!
3、我又使用i 与 i+1相比较的形式重新组织了一遍代码:

    public int maxProfit(int[] prices) {
        if(prices.length == 0)
            return 0;
        int low = 0,high = 0;
        int profit = 0;
        for(int i=0;i<prices.length-1;i++){//length - 1
            if(prices[i] >= prices[i+1]){
                profit += prices[high] - prices[low];
                low = i + 1;
            }
             high = i + 1;//这里是关键,high每次取i的下一位
        }
        //最后一步的补充运算
        profit += prices[high] - prices[low];

        return profit;
    }

最后,如果是【。。3,4】,那么low会指向3,high会指向4;如果是【。。。。4,3】,low和high都会指向3 ⇒ 适用于每种情况。所以最后的补充运算形式如上。
注意:凡是和子数组相关的题目,最后判断条件极可能是low < high或者low <= high 。
4、我查阅了一下别人的代码,发现貌似不太一样!他们的意思是,如果今天的价格比昨天高就先卖掉股票,把差值加入利润,即昨天买入,今日卖出。如果明天比今天价格还高,那就可以今天买入,明天卖出,再加入差值。代码如下:

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

        }

        return profit;
    }

事实证明,这个方法和我的结果是一样的,eg:[1,4,7],我的结果是:7-1=6;他们的做法是(4 - 1) + (7 - 4) = 6。都对!不过他们的貌似更适合现实的想法。

参考:https://www.jianshu.com/p/34bbb0594bd9
https://www.cnblogs.com/grandyang/p/4280803.html
http://blog.csdn.net/pistolove/article/details/43155725

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值