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的情况下 ...
随机推荐
- URAL 1133. Fibonacci Sequence
题目链接 #include <cstdio> #include <string> #include <cstring> #include <iostream& ...
- 显式激活数据库( ACTIVATE DATABASE)
某天值班员联系我说,我负责的一套报送系统没有按时生成报文,因为此报警提前量比较大,加上系统经常发生未按时生成报文的事件,也就是没在意,然后不急不慢的到公司,打开系统页面,发现其中一个存储过程跑了将近8 ...
- html下拉菜单的实现
这是简单的下拉菜单 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...
- 李洪强漫谈iOS开发[C语言-048]-打印平方表
打印平方表
- c++ 符号执行顺序小例子
if ( a[i] == b[i] && ++i < 0) 这个表达式的执行顺序 1. ; )// 输出 True cout<<"True"&l ...
- 8.0/9.0 Email 设置
Email 设置一直都是Odoo的一个坑,巨坑. 先讲结论,发邮件可以用,收还是算了吧 1. 发邮件设置 发的设置相对简单,如果企业邮箱支持catcll all功能,基本不用改动可以直接用,否则需要安 ...
- Codeforces Round #196 (Div. 2)
A 题意:O(-1) 思路:排个序搞定. B 题意:O(-1) 思路:坑了我好久,这个框框水平垂直比例固定,分两种情况即可,不能旋转,我想多了,分了四种情况. C 题意:一列n个位置,让你填m个数,当 ...
- FIO 测试磁盘iops 以及读写
最近在做mariadb的性能,感觉io 有瓶颈,就使用fio 来测试一下磁盘.下文为转载文章(温馨提示:此命令很伤硬盘,测试前请备份数据,- -我就写坏了一个.) FIO 是测试IOPS的非常好的工具 ...
- PowerDesigner的使用一
首先我们需要创建一个测试数据库,为了简单,我们在这个数据库中只创建一个Student表和一个Major表.其表结构和关系如下所示. 看看怎样用PowerDesigner快速的创建出这个数据库吧. 1. ...
- jsp页面向后台传值出现乱码的问题
1.采用decode()方法 页面: Url: '<%=path%>/sfyh/infodata.jsp?type='+encodeURI(ss) , 后台: String result ...