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

DawnTraveler發表於2024-06-23

1.題目

題目地址(122. 買賣股票的最佳時機 II - 力扣(LeetCode))

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/

題目描述

給你一個整數陣列 prices ,其中 prices[i] 表示某支股票第 i 天的價格。

在每一天,你可以決定是否購買和/或出售股票。你在任何時候 最多 只能持有 一股 股票。你也可以先購買,然後在 同一天 出售。

返回 你能獲得的 最大 利潤

示例 1:

輸入:prices = [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:

輸入:prices = [1,2,3,4,5]
輸出:4
解釋:在第 1 天(股票價格 = 1)的時候買入,在第 5 天 (股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5 - 1 = 4。
最大總利潤為 4 。

示例 3:

輸入:prices = [7,6,4,3,1]
輸出:0
解釋:在這種情況下, 交易無法獲得正利潤,所以不參與交易可以獲得最大利潤,最大利潤為 0。

提示:

  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104

2.題解

2.1 動態規劃

思路

動態規劃最重要的是找到狀態轉移方程:1.哪兩種狀態 2.轉移的值是什麼
在這裡:
1.持有股票/未持有股票
2.當前利潤

三步走:
1.初始化
2.狀態轉移
3.返回結果

程式碼

  • 語言支援:C++

C++ Code:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        // 初始化沒有股票和持有股票的情況
        int dp0 = 0, dp1 = -prices[0]; 
        int n = prices.size();
        for(int i = 1; i < n; i++){
            // 當前未持有股票:上一次就未持有股票 / 上一次持有股票本次賣掉
            dp0 = max(dp0, dp1 + prices[i]); 
            // 當前持有股票: 上一次就持有股票 / 上一次未持有股票本次買入
            dp1 = max(dp1, dp0 - prices[i]);
        }
        return dp0;
    }
};

複雜度分析(最佳化後)

  • 時間複雜度:\(O(n)\),同上。
  • 空間複雜度:\(O(1)\),因為只用了常數個額外變數。

2.2 貪心演算法

思路

這裡貪心的主要策略是實現區域性最優的方式,我們很容易發現,假設我們選擇從1買入,5賣出的方式區域性最優;
那麼我們1買入,2賣出;2買入,3賣出....4買入,5賣出這樣的選擇也是最優的
也就是說,我們可以將區間長度選擇簡短為1,每次都選擇淨利潤大於0的買入賣出即可!

程式碼

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int ans = 0, n = prices.size();
        for(int i = 1; i < n; i++){
            ans += max(0, prices[i] - prices[i-1]);
        }
        return ans;
    }
};

複雜度分析

  • 時間複雜度:\(O(n)\),其中\(n\)是價格陣列的長度。我們只需遍歷一次價格陣列。
  • 空間複雜度:\(O(1)\),因為只使用了常數個額外變數。

相關文章