410. 分割数组的最大值

299 篇文章 1 订阅
227 篇文章 1 订阅
本文解析了一道关于将非负整数数组分成m个子数组,最大化每个子数组和的最小值问题。通过理解问题本质并利用二分查找策略,提供了详细的算法实现和解释。适合对LeetCode 1263题目的理解与解决方法感兴趣的技术人员。
摘要由CSDN通过智能技术生成

给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。

设计一个算法使得这 m 个子数组各自和的最大值最小。

示例 1:

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

输入:nums = [1,2,3,4,5], m = 2
输出:9
示例 3:

输入:nums = [1,4,4], m = 3
输出:4

提示:

1 <= nums.length <= 1000
0 <= nums[i] <= 106
1 <= m <= min(50, nums.length)

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

此题就一个字,难理解,一开始读完题是懵的,完全不知道啥意思,找最大值的最小值,绕死了,甚至看了一遍官方的题解也没明白,最后看到有人的评论很详细,直接把我点通了,此题使用二分法进行解答:

在编写代码之前,需要先了解,数组的最大值的最小值一定是处在 【数组中最大的值——数组总值】之间的,比如题中给的例子,7,2,5,10,8,最大值是 10,总和是 32,所以最后的结果一定处在这两个数之间,将结果分为两组,7,2,5 和 10,8 所以最大值是 18,是满足提议最小的。

确定了左右边界以后,开始判断二分法的条件,假设最大值是 mid,进入判断区,此区域主要是判断,当 最大值是 mid 的时候,能够分多少组,count 代表分组的个数,sum 表示当前组的元素的总和,如果此时 sum 加上 下一个数的结果大于 target,说明要开始新的分组了,所以让 count++, 同时让 sum 处置化为下一个元素。

确定了判断区的内容,下面来说一下二分的判断,
如果此时 count 与 m 相等,说明此时的 mid 满足条件,但是不确定比 mid 小的元素是否也满足,所以要让 右边界缩短,mid = right - 1。
如果此时 count 大于 m,说明以值 mid 分的组太多了,也就是 mid 的值太小,需要扩大 mid,让 left = mid + 1 即可。
如果此时 count 小于 m,说明以值 mid 分的组太少了,也就是 mid 的值太大,导致分组少,此时同样让右边界缩短即可,mid = right - 1

class Solution {
    public int splitArray(int[] nums, int m) {
        int left = 0, right = 0;
        for (int num : nums) {
            left = Math.max(num, left);
            right += num;
        }
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (check(nums, mid, m)) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
    public boolean check(int[] nums, int target, int m) {
        int sum = 0, count = 1;
        for (int num : nums) {
            if (sum + num > target) {
                count++;
                sum = num;
            } else {
                sum += num;
            }
        }
        return count <= m;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_努力努力再努力_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值