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;
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的情况下 ...
随机推荐
- Linux进程间通信:IPC对象——信号灯集详解
作者:倪老师,华清远见嵌入式学院讲师. 一.信号灯概述 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制.相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时 ...
- linux下转换U盘文件系统
打算在windows 7 下复制一个12G 的文件至U盘,无奈U盘为FAT32格式,最大支持移动4G 的文件,只能将U盘文件系统格式化为NTFS.windows 7系统出现问题,转化中总是出现错误.故 ...
- express3.0安装并使用layout模板
转自:http://cnodejs.org/topic/5073989b01d0b801480520e4 1.安装 express-partials. 方法一:运行 cmd 用 npm install ...
- 学习使用vim,熟悉Linux
随着对vim一步一步的熟悉,对Linux的资料查阅,在加上今天阅读了王垠的文章,更加的觉得学习vim是正确的选择.抛弃Windows思维,进入Linux的世界,才发现是思维上的转变,如学习英语一样,是 ...
- HTML 插入视频
HTML 5 video 视频标签全属性详解 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.C ...
- iframe自适应高度js
<iframe src="http://www.fufuok.com/" id="iframepage" name="iframepage&qu ...
- JSP + AJAX完整实例及代码
(1)发送请求index.jsp,注意引入jquery.min.js文件 <%@ page language="java" contentType="text/ht ...
- thinkphp框架3.2的cookie删除问题记录
在使用框架删除cookie时,发现cookie(null)不起作用.后来查看官网相关信息,看到了讨论http://www.thinkphp.cn/bug/2602.html
- CloudSim样例分析
自带八个样例描述: cloudsim-2.1.1\examples目录下提供了一些CloudSim样例程序,每个样例模拟的环境如下: (1)CloudSimExample1.Java:创建一个一台主机 ...
- CSS3初学篇章_6(自定义动画)
自定义动画 由于有一部分低版本的浏览器并不支持的问题,所以这个样式要多做兼容,各大浏览器兼容前缀如下: 前缀 浏览器 -webkit chrome和safari -moz firefox - ...