zoukankan      html  css  js  c++  java
  • lintcode:买卖股票的最佳时机 III

    买卖股票的最佳时机 III

    假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易

    样例

    给出一个样例数组 [4,4,6,1,1,4,2,5], 返回 6

    解题

    尝试参考买卖股票的最佳时机 II  提交运行发现错误,每次找到连续的递增子数组记录前后的差值,找到两个最大的。如下程序,其实有问题,最大的差值,可能跨两个子数组的。

    如:{1,2,4,2,5,7,2,4,9,0}

    三个递增数组:{1,2,4}、{2,5,7}、{2,4,9},起始数组的差是:3、5、7,最大两个和是;5+7= 12

    然后对前两数组,第二个数组的起始数大于第一个的起始数,而第二个的结束数大于第一个的结束数,通过递增子数组还大于2个,所有有个更大的其实数组差是:7-1 = 6.

        public int maxProfit(int[] A) {
            // write your code here
            if(A == null || A.length == 0)
                return 0;
            if(A.length == 1)
                return 0;
            int sum=0;
            int i = 0;
            int j = 0;
            int subSum1 = Integer.MIN_VALUE;
            int subSum2 = Integer.MIN_VALUE;
            int tmpSum = 0;
            while(i < A.length && j < A.length){
                tmpSum = 0;
                while(j<A.length-1 && A[j] <= A[j+1])
                    j++;
                tmpSum += A[j] - A[i];
                if(subSum1 > subSum2){ // subSum1 是较小者
                    int tmp = subSum1;
                    subSum1 = subSum2;
                    subSum2 = tmp;
                }
                // 当 tmpSum 比较小 subSum1  大 的时候更新sumSum1
                if(tmpSum > subSum1){
                    subSum1 = tmpSum;
                }
                i = j + 1;// 下一个位置从新开始
                j = j + 1;
            }
            if( subSum2 == Integer.MIN_VALUE)
                return subSum1;
            return subSum1 + subSum2;
        }
    View Code

    题目标签中有个前后遍历,就想到定义两个数组

    left[i] 表示0 - i 并且i是卖出的最大收益

    right[i] 表示i - A.length-1 并且i 是买入的最大收益

    最后求两个数组的最大和,但是这里时间复杂度是O(N^2)可以进一步的降低的

    class Solution {
        /**
         * @param prices: Given an integer array
         * @return: Maximum profit
         */
        public int maxProfit(int[] A) {
            // write your code here
            if(A == null || A.length == 0)
                return 0;
            if(A.length == 1)
                return 0;
            int sum=0;
            int[] left = new int[A.length];
            int[] right = new int[A.length];
            int min = A[0];
            //  left[i] 表示在 0 - i 中能够 卖出的最大收益,当是 0的时候表示不买也不卖
            for(int i =1;i< A.length;i++){
                if(min<= A[i]){
                    left[i] = A[i] - min;
                }else
                    min = A[i];
            }
            int max = A[A.length - 1];
            // right[i] 表示在 i - A.length-1 中能够卖出的最大收益
            for( int i = A.length -2;i>=0;i--){
                if(max >= A[i]){
                    right[i] = max - A[i];
                }else{
                    max = A[i];
                }
            }
            max = Integer.MIN_VALUE;
            for(int i = 0;i< A.length;i++){
                for(int j = i;j<A.length;j++)
                    max = Math.max(max,left[i] + right[j]);
            }
            return max;
        }
    };

    如果我们更改定义的两个数组

    left[i] 表示0 - i 这段数组的最大收益

    right[i] 表示i - A.length-1 这段数组的最大收益

    在求两个数组的和时候只需要线性的时间复杂度

    class Solution {
        /**
         * @param prices: Given an integer array
         * @return: Maximum profit
         */
        public int maxProfit(int[] A) {
            // write your code here
            if(A == null || A.length == 0)
                return 0;
            if(A.length == 1)
                return 0;
            int sum=0;
            int[] left = new int[A.length];
            int[] right = new int[A.length];
            int min = A[0];
            //  left[i] 表示在 0 - i 中能够 卖出的最大收益,当是 0的时候表示不买也不卖
            for(int i =1;i< A.length;i++){
                if(min<= A[i]){
                    left[i] = Math.max(left[i-1], A[i] - min);
                }else{
                    left[i] = left[i-1];
                    min = A[i];
                }
                    
            }
            int max = A[A.length - 1];
            // right[i] 表示在 i - A.length-1 中能够卖出的最大收益
            for( int i = A.length -2;i>=0;i--){
                if(max >= A[i]){
                    right[i] = Math.max(right[i+1],max - A[i]);
                }else{
                    right[i] = right[i+1];
                    max = A[i];
                }
            }
            max = Integer.MIN_VALUE;
            for(int i = 0;i< A.length;i++){
                max = Math.max(max,left[i] + right[i]);
            }
            return max;
        }
    };
  • 相关阅读:
    HDFS升级域:Upgrade Domain
    HDFS升级域:Upgrade Domain
    HDFS数据快速拷贝方案:FastCopy
    HDFS数据快速拷贝方案:FastCopy
    Confluence 6 SQL Server 测试你的数据库连接
    Confluence 6 SQL Server 输入你的数据库细节
    Confluence 6 SQL Server 创建一个数据库和数据库用户
    Confluence 6 安装 SQL Server
    Confluence 6 Microsoft SQL Server 设置准备
    Confluence 6 Oracle 连接问题解决
  • 原文地址:https://www.cnblogs.com/bbbblog/p/5430265.html
Copyright © 2011-2022 走看看