| 題號 | 交易次數限制 | 核心思路 | 時間複雜度 |
|---|---|---|---|
| 121 (I) | 最多 1 次 | 前綴最小值 + 當前利潤 | O(n) |
| 122 (II) | 無限次 | 累加所有上升段利潤 | O(n) |
| 123 (III) | 最多 2 次 | 前綴最優 + 後綴最優 分治 | O(n) |
維護歷史最低買入價,計算當天賣出利潤,取最大值。
int maxProfit(vector& prices) {
int minPrice = INT_MAX, maxProfit = 0;
for (int p : prices) {
minPrice = min(minPrice, p);
maxProfit = max(maxProfit, p - minPrice);
}
return maxProfit;
}
貪心:只要明天價格高於今天,今天買明天賣。等價於累加所有上升段差值。
int maxProfit(vector& prices) {
int profit = 0;
for (int i = 1; i < prices.size(); ++i)
if (prices[i] > prices[i-1])
profit += prices[i] - prices[i-1];
return profit;
}
分治動態規劃:
int maxProfit(vector& prices) {
int n = prices.size();
if (n <= 1) return 0;
vector left(n), right(n);
int minPrice = prices[0];
for (int i = 1; i < n; ++i) {
minPrice = min(minPrice, prices[i]);
left[i] = max(left[i-1], prices[i] - minPrice);
}
int maxPrice = prices[n-1];
for (int i = n-2; i >= 0; --i) {
maxPrice = max(maxPrice, prices[i]);
right[i] = max(right[i+1], maxPrice - prices[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i)
ans = max(ans, left[i] + right[i]);
return ans;
}
DP 狀態:`dp[k][i]` = 前 i 天最多 k 筆交易最大利潤。優化至 O(kn) 時間、O(n) 空間。當 k ≥ n/2 時退化為 II 題貪心。