Back to blog
Dec 05, 2024
5 min read

LeetCode 410: Split Array Largest Sum

Leetcode 410: Split Array Largest Sum solution in Python

Problem Description

LeetCode Problem 410

Given an integer array nums and an integer k, split nums into k non-empty subarrays such that the largest sum of any subarray is minimized.

Return the minimized largest sum of the split.

A subarray is a contiguous part of the array.

 

Example 1:

Input: nums = [7,2,5,10,8], k = 2 Output: 18 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [7,2,5] and [10,8], where the largest sum among the two subarrays is only 18.

Example 2:

Input: nums = [1,2,3,4,5], k = 2 Output: 9 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [1,2,3] and [4,5], where the largest sum among the two subarrays is only 9.

 

Constraints:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 106
  • 1 <= k <= min(50, nums.length)

Difficulty: Hard

Tags: array, binary search, dynamic programming, greedy, prefix sum

Rating: 97.72%

Solution Approach

The solution uses binary search to find the optimal maximum subarray sum

  1. Search Space:

    • The minimum possible value for the largest sum is max(nums) (when k equals the array length)
    • The maximum possible value is sum(nums) (when k = 1)
  2. Decision Problem:

    • Instead of directly finding the minimum largest sum, we can solve an easier decision problem
    • For a given target sum S, can we split the array into k or fewer subarrays such that no subarray sum exceeds S?
  3. Binary Search Application:

    • If we can split the array with a certain maximum sum, we might be able to do better (try a smaller sum)
    • If we can’t split the array with a certain maximum sum, we need to increase our target

Implementation

Here’s the solution with detailed explanations:

class Solution:
    def splitArray(self, nums: List[int], k: int) -> int:
        def canSplit(max_sum):
            # This helper function checks if we can split the array into k or fewer
            # subarrays while keeping each subarray's sum <= max_sum
            count = 1  # Start with one subarray
            current_sum = 0
            
            for num in nums:
                # If adding current number exceeds max_sum,
                # we need to start a new subarray
                if current_sum + num > max_sum:
                    count += 1
                    current_sum = num
                else:
                    current_sum += num
                    
            return count <= k  # Can we achieve k or fewer splits?
        
        # Initialize binary search boundaries
        left = max(nums)   # Minimum possible maximum sum
        right = sum(nums)  # Maximum possible maximum sum
        result = right     # Initialize with worst case
        
        # Binary search for the smallest valid maximum sum
        while left <= right:
            mid = left + (right - left) // 2
            
            if canSplit(mid):
                # If we can split with this max_sum, try a smaller value
                result = mid
                right = mid - 1
            else:
                # If we can't split with this max_sum, try a larger value
                left = mid + 1
        
        return result

Algorithm Steps

  1. Binary Search Setup:

    • The search space is from max(nums) to sum(nums)
    • If k = 1, the answer is sum(nums)
    • If k = length of nums, the answer is max(nums)
    • Any valid answer must lie within this range
  2. The Helper Function (canSplit):

    • Takes a target maximum sum as input
    • Greedily tries to form subarrays
    • Keeps track of current subarray sum
    • Starts a new subarray when adding the next number would exceed the target
    • Returns whether we can achieve the split with k or fewer subarrays
  3. Binary Search Process:

    • For each middle point, we check if it’s possible to split the array
    • If possible, we try a smaller maximum sum
    • If not possible, we try a larger maximum sum
    • We keep track of the smallest valid maximum sum found

Time and Space Complexity

  • Time Complexity: O(n×log(sum(nums)))O(n × log(sum(nums)))

    • Binary search range: sum(nums) - max(nums)
    • Each canSplit call takes O(n) time
  • Space Complexity: O(1)O(1)

    • Only uses a constant amount of extra space

Example Walkthrough

Let’s walk through Example 1: nums = [7,2,5,10,8], k = 2

  1. Initial setup:

    • left = max(nums) = 10
    • right = sum(nums) = 32
  2. First iteration:

    • mid = 21
    • Can split: [7,2,5] [10,8]
    • Update right = 20
  3. Second iteration:

    • mid = 15
    • Cannot split (would need 3 subarrays)
    • Update left = 16
  4. Process continues until we find the optimal value of 18