一天一大 leet(分割数组的最大值)难度:困难-Day20200725
时间:2022-07-25
本文章向大家介绍一天一大 leet(分割数组的最大值)难度:困难-Day20200725,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:
给定一个非负整数数组和一个整数 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,在所有情况中最小。
抛砖引玉
动态规则
思路
- 声明dp记录长i的数组分割成j段,每段和最大值组成的list中最小的值
7,2,5 |
10,8 |
---|---|
sum1 |
sum2 |
dp[3][1] |
dp[5][2] |
- dp[i][j] -> 前i个数字分割成j段,每段和的最大值中的最小值
- nums中增加一个元素时,这个元素一定是要追加到最后一个分段里面
- 那此时dp[i][j]要存放的值是上一个位置的结果dp[i-x][j-1]和最后一个分段[x-i]和中较大的值
- 其中x是最后一个分段的起点,例子中的4
- x的取值:j-1到i,即最后一段最长是j-1,最短i
- 最长时前面每段一个
- 最短时只有最后一个元素
- 每增加一个元素遍历m进行分割,得到每个分割段最大值
- 再将所有分割组合得到的最大值存放到dp中,如果之前该位置出现过较小的结果则不替换
边界
- dp[0][0],0个数分成0段默认0
- dp[0][0]被默认占用则dp需要声明成[len+1][m+1]的数组
- 在分割nums时逐个增加元素,存在m大于当前给定数组的情况,怎么遍历分割时,j的边界为m与i中较小的值
/**
* @param {number[]} nums
* @param {number} m
* @return {number}
*/
var splitArray = function(nums, m) {
let len = nums.length,
sumList = Array(len + 1).fill(0),
dp = Array.from({ length: len + 1 }, () => Array(m + 1).fill(Number.MAX_VALUE));
// 逐位增加,反面后面根据区间求区间和
for (let i = 0; i < len; i++) {
sumList[i + 1] = sumList[i] + nums[i];
}
// 默认值
dp[0][0] = 0;
for (let i = 1; i <= len; i++) {
for (let j = 1; j <= Math.min(m, i); j++) {
// 前i个数分成j段
for (let x = j - 1; x < i; x++) {
// x最后一段的起点
// perv本轮分割完成 分段中最大的和
let prev = Math.max(dp[x][j - 1], sumList[i] - sumList[x])
// 该分割情况下最大分段和的最小值
dp[i][j] = Math.min(prev, dp[i][j])
}
}
}
return dp[len][m]
};
二分法
根据结果范围枚举可能的结果 再这个校验假设的结果是否成立
- 不管怎么分段结果都应该在nums最大值max和nums元素和sum之间
- 二分法查找max到sum之间的元素
- 检查其是否满足,逐步缩小可能的结果范围,返回可能的最小值
校验逻辑
- 假设结果val
- 遍历nums,当累加和大于val,则更换起点从超过val的第一个数算起重新累加
- 每次重置起点即形成一个片段
- 最终形成的片段数没有超过m,则说明这个假设的结果val成立
/**
* @param {number[]} nums
* @param {number} m
* @return {number}
*/
var splitArray = function(nums, m) {
let max = 0
sum = 0;
for (let i = 0; i < nums.length; i++) {
if (max < nums[i]) max = nums[i];
sum += nums[i];
}
while (max < sum) {
let mid = parseInt((sum - max) / 2, 10) + max;
// 随机选择的值成立则这个值默认为最大的可能结果继续查找
if (check(nums, mid, m)) {
sum = mid;
} else {
// 不满足,重置最小可能结果
max = mid + 1;
}
}
function check(nums, val, m) {
let sum = 0,
index = 1;
for (let i = 0; i < nums.length; i++) {
// 如果分段和大于了假设的结果说明,i是该分段的终点,形成一个分段
// index记录+1,i就成了下一个分段的起点(重置sum)开始校验下一个分段
if (sum + nums[i] > val) {
index++;
sum = nums[i];
} else {
sum += nums[i];
}
}
// 如果index即分段数量满足小于等于m则说明这个假设值成立
return index <= m;
}
// 返回最小可能结果
return max;
};
- 备胎的养成记KeepAlived实现热备负载
- 0基础搭建Hadoop大数据处理-初识
- 入坑系列之HAProxy负载均衡
- 如何开发自己的搜索帝国之Elasticsearch
- NET中解决KafKa多线程发送多主题的问题
- mysql数据与Hadoop之间导入导出之Sqoop实例
- 如何将mysql数据导入Hadoop之Sqoop安装
- 常见的几种Flume日志收集场景实战
- 教你一步搭建Flume分布式日志系统
- 几十条业务线日志系统如何收集处理?
- 0基础搭建Hadoop大数据处理-编程
- 0基础搭建Hadoop大数据处理-集群安装
- Validation of viewstate MAC failed 解决办法
- springmvc注入类 NoUniqueBeanDefinitionException: No qualifying bean of type [] is defined: expected sin
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- django restframework serializer 增加自定义字段操作
- 深入理解 PHP7 中全新的 zval 容器和引用计数机制
- python中可以声明变量类型吗
- keras中的History对象用法
- php session_decode函数用法讲解
- 解决python对齐错误的方法
- 详解pyinstaller生成exe的闪退问题解决方案
- PHP递归算法的简单实例
- Yii2框架操作数据库的方法分析【以mysql为例】
- 使用OpenCV实现道路车辆计数的使用方法
- python中tab键是什么意思
- PHP实时统计中文字数和区别
- PHP单例模式实例分析【防继承,防克隆操作】
- Python基于network模块制作电影人物关系图
- tp5(thinkPHP5框架)使用DB实现批量删除功能示例