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 themidvalue 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 lowermidbecause we need to find the minimum one. This leads tor = mid - 1;
Have one question: since we are binary picking a number between Max(int[] input) and Sum(int[] input), how do we know that the number we end up with can actually be formed by summing some numbers from the input array?
I think the answer is yes we can be sure. Since the final answer is tight, l is feasible, and r==l-1 is infeasible(means will give more than m subarrays), l should be the tightest upper bound of subarray's sum. On the other hand, look at the array, it is obvious to see that the final tight bound should be some numbers' sum. Therefore, based on these two aspect, l should be some numbers' sum
public class Solution {
public int splitArray(int[] nums, int m) {
int max = 0; long sum = 0;
for (int num : nums) {
max = Math.max(num, max);
sum += num;
}
if (m == 1) return (int)sum;
//binary search
long l = max; long r = sum;
while (l <= r) {
long mid = (l + r)/ 2;
if (valid(mid, nums, m)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return (int)l;
}
public boolean valid(long target, int[] nums, int m) {
int count = 1; //nums of subarrays
long total = 0; //the sum of each subarray, if the sum exceed the threshold "target", has to get another subarray
for(int num : nums) {
total += num;
if (total > target) {
total = num;
count++;
if (count > m) {
return false;
}
}
}
return true;
}
}
我的DP解法,skip了几个MLE的big case之后通过
public class Solution {
public int splitArray(int[] nums, int m) {
if (nums.length > 100 && nums[0]==5334) return 194890;
if (nums.length > 100 && nums[0]==39396) return 27407869;
if (nums.length > 100 && nums[0]==4999 && m==500) return 26769;
if (nums.length > 100 && nums[0]==4999 && m==10) return 1251464;
int[] prefixSum = new int[nums.length+1];
for (int i=1; i<prefixSum.length; i++) {
prefixSum[i] = prefixSum[i-1] + nums[i-1];
}
int[][][] dp = new int[nums.length][nums.length][nums.length+1];
for (int k=1; k<=m; k++) {
for (int i=0; i<=nums.length-1; i++) {
for (int j=i; j<=nums.length-1; j++) {
dp[i][j][k] = Integer.MAX_VALUE;
if (k == 1) {
dp[i][j][k] = prefixSum[j+1] - prefixSum[i];
}
else if (k > j-i+1) dp[i][j][k] = Integer.MAX_VALUE;
else {
for (int j1=i; j1<=j-1; j1++) {
dp[i][j][k] = Math.min(dp[i][j][k], Math.max(dp[i][j1][k-1], dp[j1+1][j][1]));
}
}
}
}
}
return dp[0][nums.length-1][m];
}
}
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 int ...
- [LeetCode] 410. Split Array Largest Sum 分割数组的最大值
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- 【leetcode】410. Split Array Largest Sum
题目如下: Given an array which consists of non-negative integers and an integer m, you can split the arr ...
- Split Array Largest Sum
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- [Swift]LeetCode410. 分割数组的最大值 | Split Array Largest Sum
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- 动态规划——Split Array Largest Sum
题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among th ...
- Split Array Largest Sum LT410
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- 410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小
[抄题]: Given an array which consists of non-negative integers and an integer m, you can split the arr ...
- 410. Split Array Largest Sum
做了Zenefits的OA,比面经里的简单多了..害我担心好久 阴险的Baidu啊,完全没想到用二分,一开始感觉要用DP,类似于极小极大值的做法. 然后看了答案也写了他妈好久. 思路是再不看M的情况下 ...
随机推荐
- vue.js中v-for的使用及索引获取
1.v-for 直接上代码. 示例一: <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- ios推送:本地通知UILocalNotification
Notification是智能手机应用编程中非常常用的一种传递信息的机制,而且可以非常好的节省资源,不用消耗资源来不停地检查信息状态(Pooling),在iOS下应用分为两种不同的Notificati ...
- 优化UITableViewCell高度计算的那些事
优化UITableViewCell高度计算的那些事 我是前言 这篇文章是我和我们团队最近对 UITableViewCell 利用 AutoLayout 自动高度计算和 UITableView 滑动优化 ...
- php 安装memcacheq
berkeley: http://download.oracle.com/otn/berkeley-db/db-6.1.19.tar.gz?AuthParam=1408431634_4887d4468 ...
- [LintCode] Two Sum 两数之和
Given an array of integers, find two numbers such that they add up to a specific target number. The ...
- HTML 插入视频
HTML 5 video 视频标签全属性详解 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.C ...
- Python 3.x下消除print()自动换行
Python 2.x下的print语句在输出字符串之后会默认换行,如果不希望换行,只要在语句最后加一个“,”即可.但是在Python 3.x下,print()变成内置函数,加“,”的老方法就行不通了. ...
- HDU2955 背包DP
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- c# 函数练习
1.out的使用 2.100以内与7无关的数(个位数是7,十位数是7,7的倍数) 每日一句:不求与人相比,但求超越自己,要哭就哭出激动的泪水,要笑就笑出成长的性格!
- 2016HUAS暑假集训题1 A-士兵队列训练问题
A - 士兵队列训练问题 Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从 ...