410. 分割数组的最大值/C++

本文介绍了一种使用二分法解决数组划分问题的算法,旨在将一个非负整数数组分成m个子数组,使各子数组和的最大值最小。通过调整猜测的中间值(mid),算法动态调整子数组数量,直至找到最优解。

给定一个非负整数数组和一个整数 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,在所有情况中最小。

解题思路:
使用二分法
先猜出一个mid作为答案,然后以mid为标准取划分数组。
同时记录所需数组的数量need。
如果我们分的数组个数比题目要求的多,那么就意味着我们猜的答案偏小。
然后搜寻右半边。
反之同理。

int splitArray(vector<int>& nums, int m) {
        long long lval=0,rval=0;
        for(int num:nums){
            lval = max(lval,(long long)num);
            rval += (long long)num; 
        }
        
        while(lval<rval){
            long long mid=(lval+rval)>>1,cur=0;
            int need=1;
            for(int num:nums){
                if(cur+num>mid){
                    ++need;
                    cur=0;
                }
                cur+=num;
            }
            if(need>m)
                lval=mid+1;
            else
                rval=mid;
        }
        return lval;
    }
### C++ 实现最小化分割数组最大值的算法 在解决最小化分割数组最大值的问题时,可以采用二分查找与贪心算法相结合的方法。这种方法的核心思想是通过二分查找来确定可能的最大值范围,并利用贪心算法验证当前候选值是否可行。 以下是基于引用内容和相关知识的完整实现: ```cpp class Solution { public: int splitArray(vector<int>& nums, int m) { // 确定二分查找的左右边界 long long left = 0, right = 0; for (int num : nums) { left = max((long long)left, (long long)num); // 最小可能的最大值数组中的最大元素 right += num; // 最大可能的最大值数组所有元素的和 } // 二分查找 while (left < right) { long long mid = (left + right) / 2; if (canSplit(nums, m, mid)) { // 检查是否可以在mid作为最大值的情况下分割成m段 right = mid; // 尝试缩小最大值 } else { left = mid + 1; // 增大最大值 } } return left; // 最终结果即为最小化的最大值 } private: bool canSplit(vector<int>& nums, int m, long long maxSum) { long long currentSum = 0; int segments = 1; // 初始为一段 for (int num : nums) { if (currentSum + num > maxSum) { // 当前子数组和超过maxSum segments++; currentSum = num; // 开始新的子数组 if (segments > m) return false; // 超过允许的分割数 } else { currentSum += num; // 继续累加到当前子数组 } } return true; // 如果能够成功分割,则返回true } }; ``` #### 代码解析 1. **初始化左右边界**: - `left` 表示数组中最大的单个元素值,这是分割数组时每个子数组和的下限[^4]。 - `right` 表示数组所有元素的总和,这是分割数组时每个子数组和的上限[^4]。 2. **二分查找**: - 在 `left` 和 `right` 之间进行二分查找,逐步缩小可能的最大值范围。 - 每次计算中间值 `mid`,并调用辅助函数 `canSplit` 验证是否可以在 `mid` 的限制下将数组分割成不超过 `m` 段[^2]。 3. **辅助函数 `canSplit`**: - 遍历数组,尝试将数组分割成若干段,每段的和不超过 `maxSum`。 - 如果需要的分割数超过 `m`,则返回 `false`;否则返回 `true`。 4. **返回结果**: - 当 `left == right` 时,表示找到了最小化的最大值,直接返回 `left`[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值