【ルーキートレーニング】ソードはオファー63を指します。株式の最大利益

タイトル説明:

特定の株の価格が時系列で配列されていると仮定すると、一度に株を売買することで得られる最大の利益はどれくらいですか?

例1:
入力:[7,1,5,3,6,4]
出力:5
説明:2日目(株価= 1)に買い、5日目(株価= 6)に売り、最大利益= 6-1 = 5。
販売価格は購入価格よりも高くする必要があるため、利益を7-1 = 6にすることはできないことに注意してください。

例2:
入力:[7,6,4,3,1]
出力:0
説明:この場合、トランザクションは完了していないため、最大利益は0です。

制限:
0 <=配列の長さ<= 10 ^ 5

出典:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof
著作権はLeetCodeが所有しています商用転載の場合は、公認機関にご連絡ください。非商用転載の場合は、出典を明記してください。

問題解決のアイデア:

3つの方法が採用されています。1つ
直接的な暴力、最大値を記録する変数の設定、および0への初期化です。たとえば、i日目に、その日の翌日の価格がi日目の価格よりも高い場合は、売り、最大値と比較して更新します。この方法の時間計算量と空間計算量は比較的大きく、時間計算量はO(n²)です。

2つ目の方法は、テクニックを使用することです。最大の利益を得るために、当日の価格が最も低いときに購入し、それよりも高いときに販売します。この点を考慮した後、疑問が生じますが、最終的に最高の利益を確実に得るにはどうすればよいでしょうか。2つの変数を作成できます。1つは当日と以前の最低価格を記録するために使用され、もう1つは当日の最善の利益を記録するために使用されます。ある日の2つの状況があります:
(1)今日の価格が最低価格よりも低い場合、それは今日転送できないことを意味しますが、将来的に利益を上げる可能性があるので、最低価格を更新します。
(2)今日の価格が最低価格よりも高い場合、それは今日利益を上げていることを意味します。私たちはそれを販売して、得られる利益が現在の最大利益よりも大きいかどうかを確認します。それが現在の最大利益よりも大きい場合は、最大のメリットが更新され、no以下になります。任意の操作。
このように、ループを実行した後の最大の利点は答えです。
時間計算量はO(n)です

3つ目は、dpのアイデアを使用することです。dp[i]は、i日目に取得できる最大の利益を保存するために使用されます。j日目
(1)j日目の価格が最低価格を下回っている場合は、最低価格を更新します。最大利益はj-1日目と同じです。
(2)j日目の価格が最低価格よりも高い場合、利益があります。販売後に得られる利益は、昨日の最大利益であるdp [jと比較されます。 -1]。
時間計算量は2番目の方法よりもわずかに高くなります。全体的なアイデアは2番目の方法と同じですが、dpのアイデアが2番目の方法に追加されます。問題が毎日最高の利益を得ることである場合、これはメソッドはこの問題を解決できます。

コード:

public class jianzhi_Offer_63 {
    
    
    //方法一:暴力,直接把所有情况算出进行比较,取最大。时间空间使用严重 时间复杂度O(n²)
    public int maxProfit(int[] prices) {
    
    
        int maxprice = 0;
        for (int i = 0; i < prices.length; i++){
    
    
            for (int j = i; j < prices.length; j++){
    
    
                int tmp = prices[j] - prices[i];
                maxprice = maxprice < tmp ? tmp:maxprice;
            }
        }
        return maxprice;
    }
    //方法2:我们只需要在当前最低价买入,然后想怎样让股票利益最大化,那不妨每天都卖一次去和当前最大利益比较。
    //如果今天的价格是历史最低,说明转不了,后面有可能赚的比现在多。那我们只需要将记录最低价的变量重新赋值,表示从当前最低价买入
    //如果今天价格比最低价高,说明今天能赚钱,那我们就卖出来看看是否比当前最大利益大。
    //时间复杂度O(n)
    public int maxProfit1(int[] prices) {
    
    
        if(prices.length == 0 ||prices.length == 1){
    
    
            return 0;
        }
        if(prices.length == 2){
    
    
            return prices[0] > prices[1] ? 0 : (prices[1] - prices[0]);
        }
        int maxprice = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++){
    
    
            if(prices[i] < min){
    
    
                min = prices[i];
            }else {
    
    
                maxprice = maxprice < (prices[i] - min) ? (prices[i] - min) : maxprice;
            }
        }
        return maxprice;
    }

    //方法三:使用dp数组,dp[i]存取,到目前第i天的最大利益。
    public int maxProfit2(int[] prices) {
    
    
        if(prices.length == 0 ||prices.length == 1){
    
    
            return 0;
        }
        if(prices.length == 2){
    
    
            return prices[0] > prices[1] ? 0 : (prices[1] - prices[0]);
        }

        int[] dp = new int[prices.length];
        //只有一个数的时候,无利可图
        dp[0] = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++){
    
    
            if(prices[i] < min){
    
    
                min = prices[i];
                dp[i] = dp[i - 1];
            }else {
    
    
                //比较前一天的最大利益和今天卖出的利益哪一个大,从而得到当前最大利益
                dp[i] = Math.max(prices[i] - min, dp[i-1]);
            }
        }
        //最后一天一定是最大利益
        return dp[dp.length - 1];
    }

    public static void main(String[] args) {
    
    
        jianzhi_Offer_63 obj = new jianzhi_Offer_63();

        int[] prices = new int[]{
    
    7,1,5,3,6,4};
        System.out.println(obj.maxProfit2(prices));
    }
}

おすすめ

転載: blog.csdn.net/Puppet__/article/details/115052967
おすすめ