↓快轉到主要內容
  1. LeetCode/

LeetCode 3814: Maximum Capacity Within Budget

·1 分鐘· ·
LeetCode Medium Binary-Search Sorting Prefix-Sum
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-01-18

  • 提交紀錄:Time Limit Exceeded → Accepted

解題思路
#

最多選兩台不同的機器,總成本嚴格小於 budget,讓總容量最大。

選一台的情況很簡單:所有成本 < budget 的機器取容量最大的。

選兩台時,依成本排序,固定比較貴的那台 i,另一台要從 i 前面、成本 < budget - cost[i] 的機器裡挑容量最大的:

  1. 依成本排序,建「前綴最大容量」best[j] = max(cap[0..j])。
  2. 對每個 i,用 bisect_left(costs, budget - cost[i]) 找到第一個成本太高的位置 idx,可以搭配的範圍是 [0, min(idx, i) - 1]。
  3. 答案候選是 cap[i] + best[min(idx, i) - 1]。

限制在 i 前面,是為了確保兩台是不同的機器,而且每一對只會被算一次。

我的嘗試:雙層迴圈
#

for i in range(n):
    for j in range(i + 1, n):
        if first_cost + second_cost >= budget:
            break
        max_cap = max(max_cap, first_cap + second_cap)

排序後內層有 break,但成本都很低的時候,內層幾乎會跑完,最壞 O(n^2),TLE。

中間還試過雙指針加前綴最大值的寫法(留在註解裡沒有交),最後改成 bisect 版本 AC。

正確解法
#

import bisect

class Solution:
    def maxCapacity(self, costs: List[int], capacity: List[int], budget: int) -> int:
        machines = sorted(zip(costs, capacity))
        sorted_costs = [c for c, _ in machines]

        best_prefix = []
        cur = 0
        for _, cap in machines:
            cur = max(cur, cap)
            best_prefix.append(cur)

        ans = 0
        for i, (cost, cap) in enumerate(machines):
            if cost >= budget:
                break
            ans = max(ans, cap)                                      # 只選一台
            j = min(bisect.bisect_left(sorted_costs, budget - cost), i) - 1
            if j >= 0:
                ans = max(ans, cap + best_prefix[j])                 # 選兩台
        return ans

複雜度
#

時間 O(n log n),空間 O(n)。

要特別避免的錯誤
#

  • 「嚴格小於」寫成 <=:要用 bisect_left(costs, budget - cost),找的是第一個 >= budget - cost 的位置。
  • 沒有限制在 i 前面:可能選到同一台機器兩次。
  • 忘記只選一台的情況。

面試口說整理
#

我把機器依成本排序,建前綴最大容量。只選一台時取成本低於預算的最大容量;選兩台時,固定比較貴的那台 i,用 bisect_left 找出成本低於 budget - cost[i] 的範圍,再限制在 i 之前避免重複,前綴最大值就是最好的搭配。時間 O(n log n)。

相關文章

LeetCode 3413: Maximum Coins From K Consecutive Bags
·2 分鐘
LeetCode Medium Sliding-Window Greedy Sorting Prefix-Sum Binary-Search Array
LeetCode 3413 解題筆記:最佳的 k 個袋子,一定有一端對齊某段的端點;分別算「左端對齊段的起點」和「右端對齊段的終點」(鏡像後重用同一個函式)
LeetCode 1838: Frequency of the Most Frequent Element
·1 分鐘
LeetCode Medium Sliding-Window Sorting Greedy Prefix-Sum Binary-Search Array
LeetCode 1838 解題筆記:排序後,把視窗裡的數都加到 nums[right] 的花費是 nums[right] × 長度 − 視窗總和;花費 > k 就縮左邊
LeetCode 2271: Maximum White Tiles Covered by a Carpet
·1 分鐘
LeetCode Medium Sliding-Window Greedy Sorting Prefix-Sum Binary-Search Array
LeetCode 2271 解題筆記:地毯的左端放在某段白磚的起點一定不會更差;排序後用雙指針,完整蓋住的段累加,最後一段只算部分
LeetCode 2779: Maximum Beauty of an Array After Applying Operation
·1 分鐘
LeetCode Medium Sliding-Window Sorting Binary-Search Array
LeetCode 2779 解題筆記:每個數可以變成 [x - k, x + k] 裡的任何值,一群數能變成同一個值 ⇔ 最大 - 最小 <= 2k;排序後找最長的這種視窗
LeetCode 2968: Apply Operations to Maximize Frequency Score
·1 分鐘
LeetCode Hard Sliding-Window Sorting Prefix-Sum Binary-Search Array
LeetCode 2968 解題筆記:排序後,把一段全部變成同一個值,最省的目標是中位數;用前綴和 O(1) 算花費,花費隨視窗變大而變大,可以滑動
LeetCode 1208: Get Equal Substrings Within Budget
·1 分鐘
LeetCode Medium Sliding-Window String Binary-Search Prefix-Sum
LeetCode 1208 解題筆記:每個位置的花費是 |s[i] - t[i]|,題目變成「總和 <= maxCost 的最長子陣列」