HomeLeetcode410. Split Array Largest Sum - Leetcode Solutions

410. Split Array Largest Sum – Leetcode Solutions

Description

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.

subarray is a contiguous part of the array.

Examples:

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.

Solution in Python

To solve this problem in Python, we can use a binary search approach. The goal is to minimize the largest sum of k subarrays by efficiently searching through possible values for this largest sum.

Key Concepts

  1. Binary Search:
    • The range for the largest sum of any subarray is between max(nums) (if each subarray contains one element) and sum(nums) (if all elements are in a single subarray).
    • We use binary search to find the smallest valid value for the largest sum that allows splitting into k subarrays.
  2. Feasibility Check:
    • A helper function determines whether it is possible to split the array into k subarrays such that the largest sum of any subarray is less than or equal to a given target.
Python
class Solution:
    def splitArray(self, nums: List[int], k: int) -> int:
        # Helper function to check if a target maximum sum is feasible
        def canSplit(target: int) -> bool:
            current_sum = 0
            subarrays = 1  # Start with one subarray
            for num in nums:
                if current_sum + num > target:
                    # Create a new subarray
                    subarrays += 1
                    current_sum = num
                    # If we exceed k subarrays, the target is not feasible
                    if subarrays > k:
                        return False
                else:
                    current_sum += num
            return True
        
        # Binary search range
        left, right = max(nums), sum(nums)
        result = right  # Initialize result to the upper bound
        
        while left <= right:
            mid = (left + right) // 2
            if canSplit(mid):
                # If it's feasible, try a smaller maximum sum
                result = mid
                right = mid - 1
            else:
                # If it's not feasible, try a larger maximum sum
                left = mid + 1
        
        return result

Explanation of the Code

  1. canSplit Function:
    • This checks if it is possible to split the array into k subarrays such that no subarray has a sum greater than target.
    • Iterate through nums, maintaining a current_sum for the current subarray. If adding a number exceeds target, start a new subarray.
    • Return True if k or fewer subarrays are created, otherwise False.
  2. Binary Search:
    • left: The smallest possible value for the largest sum is the maximum number in nums.
    • right: The largest possible value is the sum of all elements in nums.
    • For each midpoint mid, check if mid is a feasible maximum sum using canSplit.
      • If feasible, reduce right to search for smaller values.
      • If not feasible, increase left to search for larger values.
  3. Return the Result:
    • The smallest feasible value for the largest sum is stored in result.

Solution in C++

C++
class Solution {
public:
    int splitArray(vector<int>& nums, int k) {
        // Helper function to determine if we can split the array into
        // k or fewer subarrays such that no subarray has a sum greater than `maxSum`.
        auto canSplit = [&](int maxSum) -> bool {
            int currentSum = 0;
            int splits = 1; // Start with one subarray
            
            for (int num : nums) {
                // If adding this element exceeds maxSum, start a new subarray
                if (currentSum + num > maxSum) {
                    splits++;
                    currentSum = num; // Start a new subarray with the current number
                    if (splits > k) return false; // Too many subarrays needed
                } else {
                    currentSum += num; // Add to the current subarray
                }
            }
            return true; // Successfully split into k or fewer subarrays
        };

        // Binary search bounds
        int left = *max_element(nums.begin(), nums.end()); // Minimum possible max sum
        int right = accumulate(nums.begin(), nums.end(), 0); // Maximum possible max sum

        int result = right;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (canSplit(mid)) {
                result = mid; // Update the result as we found a feasible solution
                right = mid - 1; // Try for a smaller max sum
            } else {
                left = mid + 1; // Increase max sum as the current one is not feasible
            }
        }

        return result;
    }
};

Solution in Javascript

JavaScript
var splitArray = function(nums, k) {
    /**
     * Helper function to determine if it's possible to split the array into
     * `k` or fewer subarrays where the largest subarray sum is <= maxSum.
     * @param {number} maxSum - Maximum allowable sum for a subarray
     * @return {boolean} - True if it's possible to split, false otherwise
     */
    const canSplit = (maxSum) => {
        let subarrayCount = 1; // Start with one subarray
        let currentSum = 0;    // Sum of the current subarray

        for (const num of nums) {
            if (currentSum + num > maxSum) {
                // Create a new subarray if adding this number exceeds maxSum
                subarrayCount++;
                currentSum = num;

                // If the number of subarrays exceeds k, return false
                if (subarrayCount > k) {
                    return false;
                }
            } else {
                // Otherwise, add the number to the current subarray
                currentSum += num;
            }
        }

        return true; // Successfully split into k or fewer subarrays
    };

    // The smallest possible max sum is the largest number in the array
    let left = Math.max(...nums);
    // The largest possible max sum is the sum of all numbers in the array
    let right = nums.reduce((a, b) => a + b, 0);

    // Perform binary search to find the minimized largest sum
    while (left < right) {
        const mid = Math.floor((left + right) / 2);

        if (canSplit(mid)) {
            // If it's possible to split with this max sum, try a smaller value
            right = mid;
        } else {
            // Otherwise, increase the max sum
            left = mid + 1;
        }
    }

    // The left pointer now points to the minimized largest sum
    return left;
};

Solution in Java

Java
class Solution {
    public int splitArray(int[] nums, int k) {
        // Initialize the lower and upper bounds for binary search
        int left = getMax(nums); // Minimum possible largest sum
        int right = getSum(nums); // Maximum possible largest sum

        // Perform binary search to find the minimum largest sum
        while (left < right) {
            int mid = left + (right - left) / 2;
            // Check if it's possible to split the array with the current mid as the largest sum
            if (canSplit(nums, k, mid)) {
                right = mid; // Try for a smaller largest sum
            } else {
                left = mid + 1; // Increase the largest sum
            }
        }

        return left; // The minimum largest sum
    }

    // Helper method to find the maximum value in the array
    private int getMax(int[] nums) {
        int max = nums[0];
        for (int num : nums) {
            if (num > max) {
                max = num;
            }
        }
        return max;
    }

    // Helper method to calculate the sum of all elements in the array
    private int getSum(int[] nums) {
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        return sum;
    }

    // Helper method to determine if the array can be split into k subarrays with the largest sum <= mid
    private boolean canSplit(int[] nums, int k, int mid) {
        int currentSum = 0; // Sum of the current subarray
        int subarrays = 1; // Count of subarrays (at least one)

        for (int num : nums) {
            // If adding this number exceeds the mid value, start a new subarray
            if (currentSum + num > mid) {
                subarrays++;
                currentSum = num;
                // If the number of subarrays exceeds k, return false
                if (subarrays > k) {
                    return false;
                }
            } else {
                currentSum += num; // Add the number to the current subarray
            }
        }

        return true; // The array can be split into k or fewer subarrays
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular