首頁  >  文章  >  Java  >  LeetCode Day動態程式設計第8部分

LeetCode Day動態程式設計第8部分

WBOY
WBOY原創
2024-07-17 11:39:091028瀏覽

LeetCode DayDynamic Programming part8

121. 買賣股票的最佳時機

給你一個陣列價格,其中prices[i]是給定股票第i天的價格。

您希望透過選擇某一天買入一隻股票並選擇未來的另一天賣出該股票來最大化您的利潤。

回報您可以從本次交易中獲得的最大利潤。如果無法獲得任何利潤,則返回0。

範例1:

輸入:價格 = [7,1,5,3,6,4]
輸出:5
說明:第 2 天買入(價格 = 1),第 5 天賣出(價格 = 6),利潤 = 6-1 = 5。
請注意,不允許在第 2 天買入並在第 1 天賣出,因為您必須在賣出之前買入。
範例2:

輸入:價格 = [7,6,4,3,1]
輸出:0
說明:在這種情況下,沒有進行任何交易,最大利潤 = 0。

限制:

1 0 原始頁

方法一、貪心演算法

    public int maxProfit(int[] prices) {
        if(prices.length == 0){
            return 0;
        }

        int profit = 0;
        int buy = prices[0];
        for(int i=1; i<prices.length; i++ ){
            if(buy>=prices[i]){
                buy = prices[i];
            }else{
                profit = Math.max(profit, prices[i]-buy);
            }
        }
        return profit;
    }

時間 O(n) 空間 O(1)

方法2 動態規劃

    public int maxProfit(int[] prices) {
        if(prices.length == 0){
            return 0;
        }

        // 2 means we have 2 different status (have owned stock or not )
        int[][] dp = new int[prices.length][2];

        // if we want to own the stock we should pay for the specific price
        dp[0][0] = -prices[0];
        for(int i=1; i<dp.length; i++){
            dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], prices[i] + dp[i-1][0]);
        }
        // Arrays.stream(dp).map(Arrays::toString).forEach(System.out::println);
        return dp[dp.length-1][1];
    }

時間 O(n) 空間 O(n)
動態規劃比貪心演算法更通用,因為它不僅適用於特定問題。

方法2.1(提高空間複雜度)

    public int maxProfit(int[] prices) {
        if(prices.length == 0){
            return 0;
        }

        // 2 means we have 2 different status (have owned stock or not )
        int[] dp = new int[2];

        // if we want to own the stock we should pay for the specific price
        dp[0] = -prices[0];
        for(int i=1; i<prices.length; i++){
            dp[1] = Math.max(dp[1], prices[i] + dp[0]);
            dp[0] = Math.max(dp[0], -prices[i]);
        }
        // 
        return dp[1];
    }

這裡要小心,我們應該先處理 dp[1],因為它將使用先前的 dp[0] 而不是更新後的 dp[0]。

122. 買賣股票的最佳時機 II

給你一個整數數組prices,其中prices[i]是給定股票第i天的價格。

每天,您都可以決定購買和/或出售股票。您在任何時候最多只能持有一股股票。不過,您可以購買並在當天立即出售。

找到並返回您可以實現的最大利潤。

範例1:

輸入:價格 = [7,1,5,3,6,4]
輸出:7
說明:第 2 天買入(價格 = 1),第 3 天賣出(價格 = 5),利潤 = 5-1 = 4。
然後在第4天買入(價格=3)並在第5天賣出(價格=6),利潤=6-3=3。
總利潤為 4 + 3 = 7。
範例2:

輸入:價格 = [1,2,3,4,5]
輸出:4
說明:第 1 天買入(價格 = 1),第 5 天賣出(價格 = 5),利潤 = 5-1 = 4。
總利潤為 4。
範例 3:

輸入:價格 = [7,6,4,3,1]
輸出:0
說明:沒有辦法獲利,所以我們從來不買股票來達到最大利潤0。

限制:

1 0

    public int maxProfit(int[] prices) {
        if(prices.length <1){
            return 0;
        }

        int[][] dp = new int[prices.length][2];
        dp[0][0] = -prices[0];

        for(int i=1; i<prices.length; i++){
            //only when we do not own the stack we can buy a new stock
            dp[i][0] = Math.max(dp[i-1][1]-prices[i], dp[i-1][0]);
            dp[i][1] = Math.max(dp[i-1][0]+prices[i], dp[i-1][1]);
        }

        return dp[prices.length-1][1];
    }

捲動數組方法

    public int maxProfit(int[] prices) {
        if(prices.length <1){
            return 0;
        }

        int[] dp = new int[2];
        dp[0] = -prices[0];

        for(int i=1; i<prices.length; i++){
            //only when we do not own the stack we can buy a new stock
            dp[1] = Math.max(dp[0]+prices[i], dp[1]);
            dp[0] = Math.max(dp[1]-prices[i], dp[0]);

        }

        return dp[1];
    }

123. 買賣股票的最佳時機 III

給你一個陣列價格,其中prices[i]是給定股票第i天的價格。

找出你能獲得的最大利潤。您最多可以完成兩筆交易。

注意:您不得同時進行多項交易(即您必須先賣出股票才能再次購買)。

範例1:

輸入:價格 = [3,3,5,0,0,3,1,4]
輸出:6
說明:第 4 天買入(價格 = 0),第 6 天賣出(價格 = 3),利潤 = 3-0 = 3。
然後在第 7 天買入(價格 = 1)並在第 8 天賣出(價格 = 4),利潤 = 4-1 = 3。
範例2:

輸入:價格 = [1,2,3,4,5]
輸出:4
說明:第 1 天買入(價格 = 1),第 5 天賣出(價格 = 5),利潤 = 5-1 = 4。
請注意,您不能在第一天買入,在第二天買入並隨後賣出,因為您同時進行多項交易。您必須先賣出才能再次購買。
範例 3:

輸入:價格 = [7,6,4,3,1]
輸出:0
說明:在這種情況下,沒有進行任何交易,即最大利潤 = 0。

限制:

1 0

    public int maxProfit(int[] prices) {
        int transactions = 2;
        int[][] dp = new int[prices.length][transactions*2+1];
        for(int i=1; i<=transactions; i++){
            dp[0][i*2-1] = -prices[0];
        }

        for(int i=1; i<prices.length; i++){

            dp[i][1] = Math.max(dp[i-1][0]-prices[i], dp[i-1][1]);
            dp[i][2] = Math.max(dp[i-1][1]+prices[i], dp[i-1][2]);
            dp[i][3] = Math.max(dp[i-1][2]-prices[i], dp[i-1][3]);
            dp[i][4] = Math.max(dp[i-1][3]+prices[i], dp[i-1][4]);
        }
        Arrays.stream(dp).map(Arrays::toString).forEach(System.out::println);

        return dp[prices.length-1][4];
    }

以上是LeetCode Day動態程式設計第8部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn