312. Burst Balloons
題目網址:https://leetcode.cn/problems/burst-balloons/
題意:給一整數 array
nums
表示所有氣球上的編號。戳破第
i
個氣球, 可以獲得nums[i - 1] * nums[i] * nums[i + 1]
枚硬幣。其中i - 1
和i + 1
代表與i
相鄰的兩個氣球之編號。若i - 1
或i + 1
超出了nums
的邊界, 則將其看作是編號為1
的氣球。返回戳破所有氣球所能獲得的最大硬幣數。
注意:
1 ≤ nums[i] ≤ 300
Solution:
想法:利用 DP
本題重點:
- 與其考慮先射爆哪個氣球, 不如考慮最後射爆哪個氣球。因為如果是考慮先射爆哪個氣球, 這種方式無法確定當前左、右邊的氣球編號。
- 若是考慮最後射爆哪個氣球, 則可以確定該氣球的左、右邊編號
1. 定義狀態:
dp[i][j]
:在nums[i:j]
中最後射爆index = k
的氣球- 在射爆
idx = k
的氣球前, 必須先射爆nums[i:(k-1)]
、nums[(k+1):j]
區間中的氣球2. 得到狀態轉移方程:
- 由於
dp[i][j]
只保證nums[i:j]
區間的氣球會被射爆, 且idx = k
的氣球最後才會被射爆。也就是說, 當射爆nums[k]
時, 它左邊氣球的 idx 必為i - 1
, 且右邊氣球的 idx 必為j + 1
(區間外的沒被射爆, 故 k 之左、右邊為區間外的 idx)。因為nums[i:(k-1)]
、nums[(k+1):j]
區間的氣球都已經先被射爆- 狀態轉移方程:
last = nums[i - 1] * nums[k] * nums[j + 1]
dp[i][j] = max(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + last)
3. 初始化:
dp[0][0]
:沒有氣球時, 所能獲得的最大硬幣數為0
dp[i][0]
:沒有氣球時, 所能獲得的最大硬幣數為0
。其中,1 ≤ i ≤ n + 1
dp[0][j]
:由於要求最大值, 且nums[i] > 0
, 乘積一定> 0
, 故都先初始化成0
。其中,1 ≤ j ≤ n + 1
class Solution { |
- time:$O(n^3)$ ➔ for loop, 其中
n
為氣球的數量 - space:$O(n^2)$ ➔
dp
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論