标签:imp com pre public leetcode nim get lan one
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
l = max number of array; r = sum of all numbers in the array;
Every time we do mid = (l + r) / 2;
mid
.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;
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 }
Leetcode: Split Array Largest Sum
标签:imp com pre public leetcode nim get lan one
原文地址:http://www.cnblogs.com/EdwardLiu/p/6132573.html