zoukankan      html  css  js  c++  java
  • 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+14. 如果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;
        }
    }
  • 相关阅读:
    火焰图&perf命令
    C10K问题
    cocosStudio中使用PageView,ListView和ScrollView
    vim基本命令
    Git命令学习总结(-)
    可在 html5 游戏中使用的 js 工具库
    待飞日记(第十一篇)
    待飞日记(第十篇)
    待飞日记(第八天和第九天)
    高质量C++/C编程指南
  • 原文地址:https://www.cnblogs.com/haimishasha/p/11565495.html
Copyright © 2011-2022 走看看