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;
    }
};

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM