首页 > 其他分享 >分割数组的最大值问题

分割数组的最大值问题

时间:2022-10-20 18:47:12浏览次数:72  
标签:分割 nums int max 最大值 aim 数组 sum

分割数组的最大值问题

作者:Grey

原文地址:

博客园:分割数组的最大值问题

CSDN:分割数组的最大值问题

题目说明

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

在线测评见:LeetCode 410. Split Array Largest Sum

主要思路

我们先求整个数组的累加和,假设累加和为 sum,我们可以得到一个结论:

分割的 m 个非空连续子数组,每个数组内元素之和的范围一定(0,sum]区间内。

如果某种划分下的子数组之和的最大值为 max,则 max 首先肯定在(0,sum]区间内。

所以我们可以尝试将思路转换为:

我们先设置一个 max,子数组的累加和最大值不能超过 max 的情况下,最少可分多少部分?

假设能分 k 个部分,

如果k <= m,说明设置的 max 这种划分是满足条件的,再看 max 是否可以变的更小。

如果k > m,说明设置的 max 这种划分是不满足条件的,需要调大 max 的值。

我们可以通过二分的方式来定位 max 的值。即 max 先取(0,sum]的中点值,得到的划分部分数量为 k, 如果k <= m,则 max 继续去左边取中点位置来得到新的划分 k,

如果k > m,max 继续从右边的中点位置来得到新的划分 k 。

完整代码

class Solution {
    public static int splitArray(int[] nums, int m) {
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        int l = 0;
        int r = sum;
        int ans = 0;
        while (l <= r) {
            int mid = l + ((r - l) >> 1);
            int parts = getParts(nums, mid);
            if (parts > m) {
                // mid越大,parts才会越小
                l = mid + 1;
            } else {
                ans = mid;
                r = mid - 1;
            }
        }
        return ans;
    }

    // 达到aim要分几部分
    public static int getParts(int[] nums, int aim) {
        for (int num : nums) {
            if (num > aim) {
                return Integer.MAX_VALUE;
            }
        }
        int part = 1;
        int all = nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (all + nums[i] > aim) {
                part++;
                all = nums[i];
            } else {
                all += nums[i];
            }
        }
        return part;
    }
}

其中:int getParts(int[] nums, int aim)方法表示:

在连续子数组之和不超过 aim 的情况下,最少需要几个划分部分。

方法的主要逻辑是:

遍历数组,

如果发现某个元素的值超过了 aim,直接返回系统最大,说明无法得到划分。

如果没有超过 aim,则继续加入下一个元素,直到超过 aim,就定位出一个部分。依次类推,就可以得到最少有几个划分。

由于不回退机制,整个算法时间复杂度 O(N)

更多地,此题也可以用四边形不等式优化的动态规划来解,但是最优解是二分法

更多

算法和数据结构笔记

标签:分割,nums,int,max,最大值,aim,数组,sum
From: https://www.cnblogs.com/greyzeng/p/16810872.html

相关文章

  • tomcat中catalina.out按照时间分割(用crontab进行分割)
    具体操作log_control.sh脚本内容(最好是在服务器上vilog_control.sh进行创建文件)#!/bin/bashCUR_PWD="/root/apache-tomcat-8.5.42/logs/catalina_out_bak"NEWLOG=/ca......
  • 【力扣每日一题】第一题,一维数组的动态和
    题目给你一个数组nums。数组「动态和」的计算公式为:runningSum[i]=sum(nums[0]…nums[i])。请返回nums的动态和。示例1输入:nums=[1,2,3,4]输出:[1,3,6,10]解释:动态......
  • 26 数组作为函数参数
    01数组元素作为函数实参数组元素可以用作函数实参,不能用作形参。在用数组元素作函数实参时,把实参的值传给形参,是“值传递”方式。数据传递的方向是从实参传到形参,单向传递......
  • 练习27 求最大值
    练习27要求:从键盘输入两个数,求出其最大值(要求使用函数完成求最大值,并在主函数中调用该函数)程序示例如下://从键盘输入两个数,求出其最大值(要求使用函数完成求最大值,并在主函数......
  • 用CNN实现全景图像语义分割!
    作者:张强,Datawhale成员相信许多读者体验过b站上的全景视频,如果还没有,快来体验一下吧[1]!只需鼠标点击并移动,便可360度无死角的浏览全景视频,让人如同身临其境。全景图像,又称36......
  • 前后端分离数组传递问题(springboot)(Vue)
    前后端分离数组传递问题昨天与前端对接时,我后端需要List的数据,就是找不到参数,我看了前端代码也没发现问题。绝问题解决过程我的后端代码:@Transactional@PostM......
  • Linq分组取分组中的最大值,并且拿到最大值对应的id
    Linq分组取分组中的最大值,并且拿到最大值对应的idList<PhoneCallCTIPushData>phoneCallCTIPushDatas=newList<PhoneCallCTIPushData>();P......
  • CV语义分割实践指南!
     Datawhale干货 作者:徐和鼎,浙江大学,Datawhale优秀学习者遥感技术已成为获取地表覆盖信息最为行之有效的手段,已经成功应用于地表覆盖检测、植被面积检测和建筑物检测任务。......
  • 数组下标从0开始的原因
     对于数组元素的访问在操作系统层其实就是对特定内存偏移量的数据的访问,换而言之即如果想要访问一个数组的某一个元素的值那么首先就要计算它的地址偏移量,其大概的公式......
  • Java数组快速排序
    https://blog.csdn.net/weixin_44194075/article/details/1138504761.快速排序的思想​通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的......