zoukankan      html  css  js  c++  java
  • 410分割数组的最大值

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

    链接:https://leetcode-cn.com/problems/split-array-largest-sum/

    法一:自己的代码     超时,不能用

    思路:典型的二维动态规划

    from typing import List
    class Solution:
        def splitArray(self, nums: List[int], m: int) -> int:
            size = len(nums)
            dp = [[0] * m for i in range(size)]
            # 先对第一列特殊处理
            dp[0][0] = nums[0]
            for i in range(1,size):
                dp[i][0] = dp[i-1][0] + nums[i]
            # dp[i][j]表示nums前i个数分成j组的和的最大值中的最小值
            for col in range(1, m):
                for row in range(col,size):
                    dp[row][col] = min(max(dp[i][col-1], sum(nums[i+1:row+1])) for i in range(row))
            return dp[-1][-1]
    View Code

    法二:二分法

    思路:二分法的关键是对什么进行分割搜索,这道题显然不能对索引进行分割搜索,而是直接对最后的结果进行二分搜索,最后的结果要求的是最大和值中的最小值,于是可以对最后的这个最小值进行二分,每确定一个最小值,相应的就可以确定一个分割的组数k,而组数必须是m,所以为了使k=m,就要缩小搜索区间,最终使k=m,

    from typing import List
    class Solution:
        def splitArray(self, nums: List[int], m: int) -> int:
            left, right = max(nums),sum(nums)
            while left < right:
                mid = (left + right) // 2
                # cnt表示子数组的最大和大于mid的情况下,分组的的最小值,
                sums, cnt = 0, 1
                for i in nums:
                    # 这里是关键,如果此时的分组的和将要超过最大值了,则开始下一个分组
                    # 这样就保证了每个分组的和都不超过最大值,
                    if sums + i > mid:
                        cnt += 1
                        sums = i
                    else:
                        sums += i
                # 小于m,说明分组太少,导致最大值太大,故缩小最大值的右边界
                if cnt <= m:
                    right = mid
                # 大于m,说明分组太多,导致最大值太小,故增大最大值的左边界
                else:
                    left = mid + 1
            return left
    if __name__ == '__main__':
        solution = Solution()
        # result = solution.splitArray(nums=[1,2,3,1,1,1,1,1,1], m=3)
        result = solution.splitArray(nums=[1,2,3,1,1,1,1,1,1], m=3)
        print(result)
    View Code

    ttt

  • 相关阅读:
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Navicat查询哪些表有指定字段名
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12380927.html
Copyright © 2011-2022 走看看