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

LeetCode 410: Split Array Largest Sum

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

基本資料
#

難易度: hard 第一次嘗試:2026-08-26

  • 提交紀錄:Accepted(一次通過)

解題思路
#

這題可以用切 k 段的分割 DP(O(k · n^2)),但有更快的做法:對答案二分搜尋。

答案(最大段的和)有單調性:上限 mid 越大,越容易切成 k 段以內。給定 mid:

  • 貪心:從左往右,能塞進目前這段就塞,塞不下就開新的一段。這樣切出來的段數是最少的。
  • 段數 <= k:mid 可行,往小找。否則往大找。

搜尋範圍:下界是 max(nums)(每段至少要放得下最大的那個),上界是 sum(nums)(只切一段)。

段數比 k 少也沒關係:可以把某些段再拆開,最大值不會變大(數字都非負)。

我的解法
#

class Solution:
    def splitArray(self, nums: List[int], k: int) -> int:
        def pieces(limit: int) -> int:             # 每段不超過 limit 時,最少切幾段
            count, cur = 1, 0
            for x in nums:
                if cur + x > limit:
                    count += 1
                    cur = 0
                cur += x
            return count

        lo, hi = max(nums), sum(nums)
        while lo < hi:
            mid = (lo + hi) // 2
            if pieces(mid) <= k:
                hi = mid                           # 可行,試更小的
            else:
                lo = mid + 1
        return lo

複雜度
#

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

要特別避免的錯誤
#

  • 下界用 0 或 1:上限比最大的數還小時,那個數放不進任何一段,貪心會算錯。
  • 可行時是 hi = mid,不是 mid - 1:mid 本身可能就是答案。

面試口說整理
#

最大段的和有單調性:上限越大越容易切成 k 段以內,所以我對答案二分搜尋。給定上限,從左往右能塞就塞,塞不下就開新的一段,得到最少段數;段數不超過 k 就往小找。下界是最大的數,上界是總和。時間 O(n log(sum))。也可以用切 k 段的 DP,但比較慢。

相關文章

LeetCode 1402: Reducing Dishes
·1 分鐘
LeetCode Hard Dynamic-Programming Greedy Sorting Array
LeetCode 1402 解題筆記:排序後從滿意度大的開始選;每多選一道放在最前面,前面選的都往後一格,總和增加「目前選的滿意度總和」,總和是正的就繼續選
LeetCode 1526: Minimum Number of Increments on Subarrays to Form a Target Array
·1 分鐘
LeetCode Hard Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 1526 解題筆記:從左往右看,每次比前一個高,多出來的高度都要新開那麼多次操作;變矮的部分可以沿用之前的操作
LeetCode 2302: Count Subarrays With Score Less Than K
·1 分鐘
LeetCode Hard Sliding-Window Prefix-Sum Binary-Search Array
LeetCode 2302 解題筆記:分數 = 總和 × 長度,都是正數,視窗越大分數越大;分數 >= k 就縮左邊,以 right 結尾的合法子陣列有 right - left + 1 個
LeetCode 2968: Apply Operations to Maximize Frequency Score
·1 分鐘
LeetCode Hard Sliding-Window Sorting Prefix-Sum Binary-Search Array
LeetCode 2968 解題筆記:排序後,把一段全部變成同一個值,最省的目標是中位數;用前綴和 O(1) 算花費,花費隨視窗變大而變大,可以滑動
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 解題筆記:地毯的左端放在某段白磚的起點一定不會更差;排序後用雙指針,完整蓋住的段累加,最後一段只算部分