What does it solve?
Split nums into k non-empty contiguous subarrays so the largest subarray sum is as small as possible. This is exactly the Book Allocation problem with a different story: books → numbers, students → subarrays.
Key insight: binary search on the answer (the max allowed subarray sum). For a candidate limit mid, greedily count how many subarrays you'd need if no subarray may exceed mid. If that count ≤ k, the limit is feasible, try smaller; otherwise go bigger. Range is [max(nums), sum(nums)] → O(N log S).
The core idea
lo = max(nums), hi = sum(nums)
while lo <= hi:
mid = (lo+hi)/2
if pieces(mid) <= k:
ans = mid; hi = mid-1
else: lo = mid+1
Complexity
Binary search runs O(log S) times over the sum range; each feasibility check is an O(N) greedy scan.
A handful of counters. No DP table (the DP formulation is O(N²k) and much slower).
Examples & edge cases
Step-by-step table
| Step | Phase | lo | hi | mid | pieces | Feasible? | Action | Best ans |
|---|
C++ implementation
#include <bits/stdc++.h> using namespace std; // How many pieces if no subarray may exceed 'limit'? int pieces(vector<int>& a, int limit) { int cnt = 1, cur = 0; for (int x : a) { if (cur + x > limit) { cnt++; cur = x; } // start a new piece else cur += x; } return cnt; } int splitArray(vector<int>& a, int k) { int lo = *max_element(a.begin(), a.end()); int hi = accumulate(a.begin(), a.end(), 0); int ans = hi; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (pieces(a, mid) <= k) { ans = mid; // feasible — try a smaller max hi = mid - 1; } else { lo = mid + 1; // too many pieces — allow bigger max } } return ans; } int main() { vector<int> a = {7,2,5,10,8}; cout << splitArray(a, 2) << "\n"; // 18 return 0; }
My Notes
📝Notes✅
Practice this problem