LeetCode 410. Split Array Largest Sum

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

v2-5249a62327ca900562c937576c46233c_1440w.jpg

Description



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:

If n is the length of array, assume the following constraints are satisfied:

1 ≤ n ≤ 1000

1 ≤ m ≤ min(50, n)


Examples:

Input:

nums = [7,2,5,10,8]

m = 2

Output:

18


Explanation:

There are four ways to split nums into two subarrays.

The best way is to split it into [7,2,5] and [10,8],

where the largest sum among the two subarrays is only 18.


描述



给定一个非负整数数组和一个整数 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

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路



  • 这道题可以使用动态规划和二分搜索来做,使用动态规划的 Python 代码会超时,因此下面使用二分搜索。
  • 对于题意,当 k 等于 nums 的元素个数时,此时的最小值就是数组的最大值;当 k = 1时,此时的最小值就是整个数组的和。
  • 因此,我们要求的结果一定在上面这两个值之间。
  • 我们给定一个值 middle,然后我们对数组分组,使得每个组中的元素尽量多,并且其和小于等于 middle,统计总共分的的总组数 group;
  • 如果 group 大于 k,说明 middle 这个值给小了,需要给一个更大的值,使得每组中容纳更多的数,使得总组数减小;
  • 如果 group 小于 k,说明 middle 这个值给大了,需要给一个更小的值,使得没组中容纳更少的数,使得总组数增多;
  • 如果 group 等于 k,说明此时把数组分成 k 组,每组的和都不大于 middle,此时我们尝试把 middle 减少 1,当用 middle 去划分数组有 k 组,middle -1 去划分数组大于 k 组时,middle 就是要求的结果。


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-10-04 11:17:10
# @Last Modified by:   何睿
# @Last Modified time: 2019-10-05 16:13:51
from typing import List
from bisect import bisect_right
class Solution:
    def splitArray(self, nums: List[int], m: int) -> int:
        prefix_sum = self.sum_cumulative(nums)
        left, right, count = max(nums), prefix_sum[-1], len(nums)
        while left < right:
            middle = left + ((right - left) >> 1)
            if self.is_greater(prefix_sum, middle, m, count):
                left = middle + 1
            else:
                right = middle
        return right
    def sum_cumulative(self, nums):
        prefix_sum = [nums[0]]
        for i in range(1, len(nums)):
            prefix_sum.append(prefix_sum[i - 1] + nums[i])
        return prefix_sum
    def is_greater(self, prefix_sum, max_num, m, count):
        pivot, start, group = max_num, 0, 0
        while start < count:
            start = bisect_right(prefix_sum, pivot, start)
            pivot = prefix_sum[start - 1] + max_num
            group += 1
            if group > m:
                return True
        return False


源代码文件在 这里


目录
相关文章
Leetcode Find Minimum in Rotated Sorted Array 题解
对一个有序数组翻转, 就是随机取前K个数,移动到数组的后面,然后让你找出最小的那个数,注意,K有可能是0,也就是没有翻转。
68 0
|
算法
LeetCode 330. Patching Array
给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。
86 0
LeetCode 330. Patching Array
LeetCode 238. Product of Array Except Self
给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
98 0
LeetCode 238. Product of Array Except Self
LeetCode 189. Rotate Array
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
88 0
LeetCode 189. Rotate Array
|
算法
LeetCode Find Minimum in Rotated Sorted Array II
假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请找出其中最小的元素。 注意数组中可能存在重复的元素。
104 0
LeetCode Find Minimum in Rotated Sorted Array II
LeetCode 153. Find Minimum in Rotated Sorted Array
假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请找出其中最小的元素。 你可以假设数组中不存在重复元素。
119 0
LeetCode 153. Find Minimum in Rotated Sorted Array
LeetCode 108. Convert Sorted Array to BST
给定一个数组,其中元素按升序排序,将其转换为高度平衡的BST。 对于这个问题,高度平衡的二叉树被定义为:二叉树中每个节点的两个子树的深度从不相差超过1。
95 0
LeetCode 108. Convert Sorted Array to BST
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
|
算法 Python
LeetCode 108. 将有序数组转换为二叉搜索树 Convert Sorted Array to Binary Search Tree
LeetCode 108. 将有序数组转换为二叉搜索树 Convert Sorted Array to Binary Search Tree
|
算法 测试技术
LeetCode 88. 合并两个有序数组 Merge Sorted Array
LeetCode 88. 合并两个有序数组 Merge Sorted Array