証券IIIを購入し、販売する【LeetCode】123、ベストタイム

トピックグレード:ハード

件名の説明:

あなたがするアレイ持っていると言う番目の要素は、日に与えられた株式の価格である私を

最大の利益を発見するアルゴリズムを設計します。あなたは完了することがあり、最大で2つの取引。

注意:あなたは(あなたが再び購入する前に、すなわち、あなたが株式を売却しなければならない)、同時に複数の取引に従事することはできません。

例1:

Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
             Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.

例2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.

例3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

  質問の意味: i番目の要素が与えられた株式のi日の価格である配列を、与えられました。得られる最大の利益を計算するためのアルゴリズムを設計します。最大2つのトランザクションを完了し、株価は再び購入する前に前に完売する必要があります。


問題解決のためのアイデア(ダイナミック・プログラミング+二分法):

  最初の二つの質問がトランザクションを許可し、変更は二つのトランザクションを可能にすることです、多くの取引を許可され、相対的な難易度が比較的大きいです。

  まず、状況を見て取引することができます、我々は明らかに問題が意思決定の各段階での意思決定を段階的に見ることができる新株発行の売却は、それによって影響の結果を最適化し、全体的な意思決定に影響を与えます。だから、問題の1つのトランザクションで、我々は解決するために、次の再帰式を使用して、動的計画法を使用しますdp[i]=max(price[i]-min,maxProfit)

  ここでは2つのトランザクションがあり、解決策は次のとおりです。2つの2のトランザクション、1の後に1、前にi番目の日、私の日に取引を変換します。

  私たちは、あなたが二分思考を使用することができますので、完了するまでに二時間後、再び、2つのトランザクションが一度完了しなければならないことがわかり、分割線としてi日、私は、私が最初の日後に完了初日前にトランザクションを完了することができますトランザクションは、それぞれ、各トランザクションの最大値を取得するために、対応する利益二回合計は、私たちが私に最も適しを見つけるために最後の時間を横断しようとの結果です。

  我々は、I [i]はiが最大の利益をDP2とトランザクションの最後の日に最初の日の完了を示し、[I]の日に取引の完了日から最大の利益を表すDP1。2つの配列は、それぞれ、DP1およびDP2ができる計算するだけでよいです。

  ときに我々最初のトラバーサルDP1のために、非常に前後からシンプル、トラバース、これは漸化式です:dp1[i]=max(dp[i-1],prices[i]-min)

  DP2は、わずかに前方にトラバースから変形されるため、最大の漸化式を維持します。dp2[i]=max(dp[i+1,max-prices[i]])

  :最後に、我々は結果を尋ねるres=max(dp1[i]+dp2[i])私の最も適切な値を見つけることです。

class Solution {
    public int maxProfit(int[] prices) {
        /*分成两次,第i天之前一次,第i天之后一次,转化成两个一次交易的问题
         从前往后:dp1[i]=max(dp[i-1],prices[i]-min),从第一天到第i天完成一次交易的最大收益
         从后往前:dp2[i]=max(dp[i+1,max-prices[i]]),从第i天到最后一天完成一次交易的最大收益
        */
        if(prices==null || prices.length==0)
            return 0;
        int len=prices.length;
        int[] dp1=new int[len];
        int[] dp2=new int[len];
        //从前往后
        int min=prices[0];
        dp1[0]=0;
        for(int i=1;i<len;i++){
            dp1[i]=Math.max(dp1[i-1],prices[i]-min);
            min=Math.min(prices[i],min);
        }
        //从后往前
        int max=prices[len-1];
        dp2[len-1]=0;
        for(int i=len-2;i>=0;i--){
            dp2[i]=Math.max(max-prices[i],dp2[i+1]);
            max=Math.max(prices[i],max);
        }
        //合并得到结果
        int res=0;
        for(int i=0;i<len;i++){
            if(dp1[i]+dp2[i]>res)
                res=dp1[i]+dp2[i];
        }
        return res;
    }
}

概要

  より困難この問題は、実際には、これは主に、動的プログラミング溶液、再帰式を書き込む権利に精通して、トランザクション・変形試験方法です。

おすすめ

転載: www.cnblogs.com/gzshan/p/11115891.html