首页 > 代码库 > 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 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
- The answer is between maximum value of input array numbers and sum of those numbers.
- 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 domid = (l + r) / 2;
- 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 thanmid
.
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 themid
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 thanmid
. We should increase m. This leads tol = 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 thanmid
, or we used up all numbers before we reach m. Both of them mean that we should lowermid
because we need to find the minimum one. This leads tor = 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 }
Leetcode: Split Array Largest Sum
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。