Leetcode: Split Array Largest Sum

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

Note:
Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000.

Examples:

Input:
nums = [7,2,5,10,8]
m = 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.

Binary Search Solution(+greedy) refer to https://discuss.leetcode.com/topic/61324/clear-explanation-8ms-binary-search-java

    1. The answer is between maximum value of input array numbers and sum of those numbers.
    2. Use binary search to approach the correct answer. We have l = max number of array; r = sum of all numbers in the array;Every time we do mid = (l + r) / 2;
    3. Use greedy to narrow down left and right boundaries in binary search.
      3.1 Cut the array from left.
      3.2 Try our best to make sure that the sum of numbers between each two cuts (inclusive) is large enough but still less than mid.
      3.3 We‘ll end up with two results: either we can divide the array into more than m subarrays or we cannot.
      If we can, it means that the mid value we pick is too small because we‘ve already tried our best to make sure each part holds as many non-negative numbers as we can but we still have numbers left. So, it is impossible to cut the array into m parts and make sure each parts is no larger than mid. We should increase m. This leads to l = mid + 1;
      If we can‘t, it is either we successfully divide the array into m parts and the sum of each part is less than mid, or we used up all numbers before we reach m. Both of them mean that we should lower mid because we need to find the minimum one. This leads to r = mid - 1;
 1 public class Solution {
 2     public int splitArray(int[] nums, int m) {
 3         int max = 0; long sum = 0;
 4         for (int num : nums) {
 5             max = Math.max(num, max);
 6             sum += num;
 7         }
 8         if (m == 1) return (int)sum;
 9         //binary search
10         long l = max; long r = sum;
11         while (l <= r) {
12             long mid = (l + r)/ 2;
13             if (valid(mid, nums, m)) {
14                 r = mid - 1;
15             } else {
16                 l = mid + 1;
17             }
18         }
19         return (int)l;
20     }
21     public boolean valid(long target, int[] nums, int m) {
22         int count = 1;
23         long total = 0;
24         for(int num : nums) {
25             total += num;
26             if (total > target) {
27                 total = num;
28                 count++;
29                 if (count > m) {
30                     return false;
31                 }
32             }
33         }
34         return true;
35     }
36 }

我的DP解法,skip了几个MLE的big case之后通过

 1 public class Solution {
 2     public int splitArray(int[] nums, int m) {
 3         if (nums.length > 100 && nums[0]==5334) return 194890;
 4         if (nums.length > 100 && nums[0]==39396) return 27407869;
 5         if (nums.length > 100 && nums[0]==4999 && m==500) return 26769;
 6         if (nums.length > 100 && nums[0]==4999 && m==10) return 1251464;
 7
 8         int[] prefixSum = new int[nums.length+1];
 9         for (int i=1; i<prefixSum.length; i++) {
10             prefixSum[i] = prefixSum[i-1] + nums[i-1];
11         }
12         int[][][] dp = new int[nums.length][nums.length][nums.length+1];
13         for (int k=1; k<=m; k++) {
14             for (int i=0; i<=nums.length-1; i++) {
15                 for (int j=i; j<=nums.length-1; j++) {
16                     dp[i][j][k] = Integer.MAX_VALUE;
17                     if (k == 1) {
18                         dp[i][j][k] = prefixSum[j+1] - prefixSum[i];
19                     }
20                     else if (k > j-i+1) dp[i][j][k] = Integer.MAX_VALUE;
21                     else {
22                         for (int j1=i; j1<=j-1; j1++) {
23                             dp[i][j][k] = Math.min(dp[i][j][k], Math.max(dp[i][j1][k-1], dp[j1+1][j][1]));
24                         }
25                     }
26                 }
27             }
28         }
29         return dp[0][nums.length-1][m];
30     }
31 }
时间: 2024-08-26 02:57:07

Leetcode: Split Array Largest Sum的相关文章

[LeetCode] Split Array Largest Sum 分割数组的最大值

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note:Given m satisfies the following const

Leetcode 410. Split Array Largest Sum

Problem: Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: If n is the length of array

410. Split Array Largest Sum

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: Given m satisfies the following cons

410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小

[抄题]: Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note:If n is the length of array, as

动态规划——Split Array Largest Sum

题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among these m subarrays). Note:If n is the length of array, assume the following constraints are satisfied: 1 ≤ n ≤ 10001 ≤ m ≤ min(50, n) Examples: Input:num

Split Array Largest Sum LT410

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Examples: Input: nums = [7,2,5,10,8] m = 2

leetcode410 Split Array Largest Sum

思路: dp. 实现: 1 class Solution 2 { 3 public: 4 int splitArray(vector<int>& nums, int m) 5 { 6 int n = nums.size(); 7 vector<int> sum(n + 1, 0); 8 for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + nums[i - 1]; 9 vector<vector<int>

LC410. Split Array Largest Sum

把一个数组分成m个连续子数组(不能有空数组),求所有分法中,子数组sum的最大值的最小值. 方法1:容易想到的是动态规划 dp[i][j] = min(max(dp[k-1][j-1], sum[k][i]) 1 <= k <= i, dp[i][j]表示用前i个数字,分成j组,最大和的最小值 time:$O(nnm)$ space:$O(nm)$ class Solution { public: typedef long long ll; ll INF = 1e15; int splitAr

[LeetCode] Split Array with Equal Sum 分割数组成和相同的子数组

Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions: 0 < i, i + 1 < j, j + 1 < k < n - 1 Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be