410 分割数组的最大值(最小化最大问题-二分查找)

1. 问题描述:

给定一个非负整数数组 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] <= 10 ^ 6
1 <= m <= min(50, nums.length)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/split-array-largest-sum

2. 思路分析:

对于最大化最小最小化最大问题一般可以考虑二分查找的方法,但是能够使用二分吗?需要判断先一下,也即能否找到一种方案,使得能够划分为m段,并且每一段的和都是小于等于mid的,答案是可以的,因为数组中的所有元素都是非负的,所以我们可以使用贪心的思想,使得当前这一段的和在满足小于等于mid的前提下包含更多的数字,也即使得段数是更少的(划分段数最少的情况下都可以满足段数是大于等于m的说明可能存在较小的和使得划分的段数是大于等于m的),这样当我们在判断当前的每一段的和是否满足mid的计算需要划分的段数,如果发现段数大于等于m说明答案应该是在左边的,因为最少的划分段数都使得段数是大于等于m的,所以可能存在和更小使得段数大于等于m,更新右边界为mid,否则说明和太小了我们需要使得和大一点,也即答案肯定是在右边,更新左边界为mid + 1即可。

3. 代码如下:

from typing import List


class Solution:
    def check(self, nums: List[int], m: int, mid: int):
        # count记录划分数组的段数
        count = 1
        s = 0
        for x in nums:
            # 不能够将x划分到任意的一段
            if x > mid: return False
            # 超出了当前的最大和需要另外一段
            if s + x > mid:
                s = x
                count += 1
            else:
                s += x
        # 判断最后一段是否超过了mid
        if s > mid: count += 1
        # 能够划分的最少段数是否小于等于m
        return count <= m

    def splitArray(self, nums: List[int], m: int) -> int:
        # 因为返回值为int所以右边界为int的最大值即可
        l, r = 0, 2147483647
        while l < r:
            mid = l + r >> 1
            if self.check(nums, m, mid):
                r = mid
            else:
                # 和太小了导致段数太多
                l = mid + 1
        return r
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值