Split Array Largest Sum

hard array binary search dp greedy

Problem

Partition nums into k non-empty contiguous subarrays so that the largest subarray sum is minimized. Return that minimum.

Inputnums = [7, 2, 5, 10, 8], k = 2
Output18
Split into [7,2,5] and [10,8]; largest sum 18 is smaller than any other split's largest.

def splitArray(nums, k):
    def pieces(cap):
        p, cur = 1, 0
        for x in nums:
            if cur + x > cap:
                p += 1
                cur = 0
            cur += x
        return p
    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
function splitArray(nums, k) {
  const pieces = (cap) => {
    let p = 1, cur = 0;
    for (const x of nums) {
      if (cur + x > cap) { p++; cur = 0; }
      cur += x;
    }
    return p;
  };
  let lo = Math.max(...nums), hi = nums.reduce((a,b)=>a+b,0);
  while (lo < hi) {
    const mid = (lo + hi) >> 1;
    if (pieces(mid) <= k) hi = mid;
    else lo = mid + 1;
  }
  return lo;
}
class Solution {
    public int splitArray(int[] nums, int k) {
        int lo = 0, hi = 0;
        for (int x : nums) { lo = Math.max(lo, x); hi += x; }
        while (lo < hi) {
            int mid = (lo + hi) >>> 1;
            if (pieces(nums, mid) <= k) hi = mid;
            else lo = mid + 1;
        }
        return lo;
    }
    private int pieces(int[] a, int cap) {
        int p = 1, cur = 0;
        for (int x : a) {
            if (cur + x > cap) { p++; cur = 0; }
            cur += x;
        }
        return p;
    }
}
class Solution {
public:
    int splitArray(vector<int>& nums, int k) {
        long lo = 0, hi = 0;
        for (int x : nums) { lo = max(lo, (long)x); hi += x; }
        auto pieces = [&](long cap) {
            long p = 1, cur = 0;
            for (int x : nums) {
                if (cur + x > cap) { p++; cur = 0; }
                cur += x;
            }
            return p;
        };
        while (lo < hi) {
            long mid = (lo + hi) / 2;
            if (pieces(mid) <= k) hi = mid;
            else lo = mid + 1;
        }
        return (int)lo;
    }
};
Time: O(n log S) where S = sum(nums) Space: O(1)