leetcode 410. 分割数组的最大值(二分法)

1. 题目描述

给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。

注意:
数组长度 n 满足以下条件:

1 ≤ n ≤ 1000
1 ≤ m ≤ min(50, n)
示例:

输入:
nums = [7,2,5,10,8]
m = 2

输出:
18

解释:
一共有四种方法将nums分割为2个子数组。
其中最好的方式是将其分为[7,2,5] 和 [10,8],
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/split-array-largest-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 思路

核心,二分查找各个子数组和的最大值的最小情况
    1. 子数组的最大值是有范围的,即在区间[max(nums),sum(nums)]之中。
    2. 令l=max(nums),h=sum(nums),mid=(l+h)/2,计算数组和最大值不大于mid对应的子数组个数cnt(这个是关键!)
    3. 如果cnt>m,说明划分的子数组多了,即我们找到的mid偏小,故l=mid+1;
    4. 如果cnt<=m,说明划分的子数组少了,即mid偏大(或者正好就是目标值),故h=mid。

3. 代码

class Solution {
    public int splitArray(int[] nums, int m) {
        /**子数组的最大值是有范围的,即在区间[max(nums),sum(nums)]之中。*/
        long l = nums[0];
        long h = 0;
        for (int i : nums) {
            h += i;//max(nums)
            l = l > i ? l : i;//sum(nums)
        }
        /**计算数组和最大值不大于mid对应的子数组个数cnt*/
        while (l<h) {//二分法找分割数组的最大值
            long mid = (l + h) / 2;
            long temp = 0;
            int cnt = 1;//初始值为1,
            for(int i:nums) {
                temp += i;
                if(temp>mid) {//如果超过mid,开启新的一组
                    temp = i;//每个子数组和
                    ++cnt;//子数组个数
                }
            }
            if(cnt>m)
                l = mid + 1;//如果cnt>m,说明划分的子数组多了,即我们找到的mid偏小,故l=mid+1;
            else
                h = mid;//如果cnt<=m,说明划分的子数组少了,即mid偏大(或者正好就是目标值),故h=mid。
        }
        return (int)l;
    }
}

原文地址:https://www.cnblogs.com/haimishasha/p/11565495.html

时间: 2024-08-27 01:42:32

leetcode 410. 分割数组的最大值(二分法)的相关文章

Leetcode 659.分割数组为连续子序列

分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5 示例 2: 输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5 示例 3: 输入: [1,2

[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 const

LeetCode 548. Split Array with Equal Sum (分割数组使得子数组的和都相同)$

Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions: 0 < i, i + 1 < j, j + 1 < k < n - 1 Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be

LeetCode——数组篇:659. 分割数组为连续子序列

659. 分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5 示例 2: 输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5 示例 3: 输入:

java实现求一个数组里最大值和最小值之前缺省的数的算法

问题描述: 求一个数组里最大值和最小值之间缺省的数,例如 int arrDemo = {1, 3, 7};  那么就要输出最小值1和最大值7之间缺少的数字2,4,5,6 代码如下,有更好的思路欢迎大家在评论区留言讨论 1 package test; 2 3 public class Test { 4 5 static int[] array = { 6 -10,0,3,3,9 7 }; 8 9 private static void printEmptyItems(int[] array) {

《返回一个数组的最大值》

设计思想:手动或使用随机函数生成一系列数组成一个数组,设计求数组中最大值的函数,在主函数中调用即可:但是考虑到用户的各种需求与程序的各种不一致性,为此设计了相关的能柔和两种状态下的各种情况测试提醒: (1)计算机会对用户有意无意输入的数组长度为0,复数,或大于分配的内存空间情况而对用户做不了用户满意的应答,故在程序中加一段对用户输入的数组长度判断的测试,则用户便可根据系统的提示一步步进行即可. (2)由于用户的无意性,可能会混淆键入不同的数据类型,然而计算机并不能愉快的解决此问题为用户得来满意的

使用JavaScript&#183;求数组的最大值和最小值

前言  在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最大值和最小值的一些方法. 法一:其实利用 ECMAScript5的 ...展开运算符可以很简单的解决这个问题 var arr=[2,7,3,10,22,11]; Math.max(...arr); //44 Math.min(...arr); //2  法二 : 对数组进行遍历 对于数组的遍历,有多种不同的方法,下面对各种方法进行比较:Arr

整数数组中子数组的最大值2

设计思路 (1)     首先设置要输入的数字个数和输入的数字: (2)     求数组number[]中子数组的最大值,运用到数组的动态规划,会运用到两个变量进行比较,一个为子数组的和,另一个为子数组和的最大值:maxnum=max{temp,maxnum}:temp和maxnum初始化为第一个数的值: (3)     依次检索每个数的值,每次将值与下一个数的值相加并将值赋值给变量temp:如果temp<0:temp再加上下一个数,temp会更小,此时将temp=0,便于不影响下一个子数组的和

获取数组中最大值和最小值

var ary = [12,23,23,4,4,12,4,141,4]; 1.利用obj存储 var min = max= null; var obj = {}; for(var i=0;i<ary.length;i++){ var cur = ary[i]; obj[cur]= cur; } var count = 0 ; for(var key in obj){ count++; if(count===1){ min = key; } max = key; } console.log(min