LeetCode 1465. 切割后面积最大的蛋糕

矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCuts 和 verticalCuts,其中:
horizontalCuts[i] 是从矩形蛋糕顶部到第 i 个水平切口的距离
verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离

请你按数组 horizontalCuts 和 verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果 对 109 + 7 取余 后返回。

示例 1:
在这里插入图片描述

输入:h = 5, w = 4, horizontalCuts = [1,2,4], verticalCuts = [1,3]
输出:4 

解释:上图所示的矩阵蛋糕中,红色线表示水平和竖直方向上的切口。切割蛋糕后,绿色的那份蛋糕面积最大。

示例 2:

在这里插入图片描述

输入:h = 5, w = 4, horizontalCuts = [3,1], verticalCuts = [1]
输出:6

解释:上图所示的矩阵蛋糕中,红色线表示水平和竖直方向上的切口。切割蛋糕后,绿色和黄色的两份蛋糕面积最大。
示例 3:

输入:h = 5, w = 4, horizontalCuts = [3], verticalCuts = [3]
输出:9

提示:

2 <= h, w <= 109
1 <= horizontalCuts.length <= min(h - 1, 105)
1 <= verticalCuts.length <= min(w - 1, 105)
1 <= horizontalCuts[i] < h
1 <= verticalCuts[i] < w

题目数据保证 horizontalCuts 中的所有元素各不相同
题目数据保证 verticalCuts 中的所有元素各不相同

题目给出一个高度为 hhh 长度为 www 的矩形蛋糕,我们需要按照水平切割方案
horizontalCuts\textit{horizontalCuts}horizontalCuts,和竖直切割方案 verticalCuts\textit{verticalCuts}verticalCuts 对蛋糕进行切割,其中 horizontalCuts[i]\textit{horizontalCuts}[i]horizontalCuts[i] 表示从矩形蛋糕顶部水平往下距离 horizontalCuts[i]\textit{horizontalCuts}[i]horizontalCuts[i] 的位置进行切割,verticalCuts[j]\textit{verticalCuts}[j]verticalCuts[j] 表示从矩形蛋糕最左侧往右距离 verticalCuts[j]\textit{verticalCuts}[j]verticalCuts[j] 的位置进行切割。现在我们需要求出切割后的面积最大的蛋糕面积对 109+710 ^ 9 + 710 9 +7 取模后的值。

首先,我们需要将水平切割和竖直切割的位置数组 horizontalCuts\textit{horizontalCuts}horizontalCuts 和 verticalCuts\textit{verticalCuts}verticalCuts 进行排序,并且在数组的开头添加 000 和结尾添加对应的矩形边界值。这是为了确保我们考虑到所有的切割位置,包括矩形的边缘。然后在排序后的切割位置数组中,我们可以计算相邻切割位置之间的间隔,以找出水平和竖直切割的最大间隔。因为每个间隔代表了一块蛋糕的尺寸,水平和竖直间隔的乘积就是对应蛋糕块的面积,所以最大面积由最大水平间隔和最大竖直间隔相乘得到。最后我们返回最大面积对 109+710^9 + 710
9+7 的取模即可。

在这里插入图片描述

C++

class Solution {
public:int maxArea(int h, int w, vector<int>& horizontalCuts, vector<int>& verticalCuts) {horizontalCuts.push_back(0);horizontalCuts.push_back(h);verticalCuts.push_back(0);verticalCuts.push_back(w);sort(horizontalCuts.begin(), horizontalCuts.end());sort(verticalCuts.begin(), verticalCuts.end());int x = 0, y = 0;for (int i = 1; i < horizontalCuts.size(); ++i) {x = max(x, horizontalCuts[i] - horizontalCuts[i - 1]);}for (int i = 1; i < verticalCuts.size(); ++i) {y = max(y, verticalCuts[i] - verticalCuts[i - 1]);}const int mod = 1e9 + 7;return (1ll * x * y) % mod;}
};

这个代码实现了一个计算蛋糕切割后最大面积的算法。它的思路是,首先将水平切割和竖直切割的位置信息添加到对应的数组中,然后对数组进行排序。接着,通过遍历这些切割位置,计算相邻两个位置之间的距离,从而得到切割后的矩形条的最大宽度和最大高度。最后,计算最大面积并返回。

这个算法的时间复杂度是O(nlogn),其中n是切割位置的数量。在排序时,使用了额外的O(n)的空间来存储排序后的数组。因此,这个算法的空间复杂度也是O(n)。

这个算法的优点是,它通过排序和遍历操作,直接得到了切割后矩形的最大宽度和最大高度,从而避免了复杂的动态规划计算。同时,它也使用了取模运算来防止结果溢出,从而保证了答案的正确性。

需要注意的是,这个算法假设切割位置的信息已经按照顺序给出了,并且没有考虑切割位置之间的间隔。如果存在间隔,需要对输入进行一些预处理,比如在每个切割位置之间插入0或其他默认值。此外,对于非数值型的切割位置,需要将其转换为数值型才能使用这个算法。

时间复杂度 O(mlog⁡m+nlog⁡n)O(m\log m + n\log n)O(mlogm+nlogn),空间复杂度 O(max⁡(log⁡m,log⁡n))O(\max(\log m, \log n))O(max(logm,logn))

其中 mmm 和 nnn 分别为 horizontalCuts 和 verticalCuts 的长度。

python

class Solution:def maxArea(self, h: int, w: int, horizontalCuts: List[int], verticalCuts: List[int]) -> int:horizontalCuts.extend([0, h])verticalCuts.extend([0, w])horizontalCuts.sort()verticalCuts.sort()x = max(b - a for a, b in pairwise(horizontalCuts))y = max(b - a for a, b in pairwise(verticalCuts))return (x * y) % (10**9 + 7)

首先,函数将矩形的起始和结束位置(0,0)和(h,w)添加到各自的切割列表中。这样做是为了确保这些位置也被视为可能的切割点。

然后,这两个列表分别进行排序。这是为了确保在查找可能的切割点时,它们是按照从左到右的顺序排列的。

接下来,函数使用pairwise函数从horizontalCuts和verticalCuts列表中分别生成一系列连续的切割点对,并计算相邻点之间的最大差值。这样做是为了找出可能的切割宽度和高度。

最后,函数返回这个最大面积值(使用取模操作,以防结果超过10^9+7)。

java

class Solution {public int maxArea(int h, int w, int[] horizontalCuts, int[] verticalCuts) {final int mod = (int) 1e9 + 7;Arrays.sort(horizontalCuts);Arrays.sort(verticalCuts);int m = horizontalCuts.length;int n = verticalCuts.length;long x = Math.max(horizontalCuts[0], h - horizontalCuts[m - 1]);long y = Math.max(verticalCuts[0], w - verticalCuts[n - 1]);for (int i = 1; i < m; ++i) {x = Math.max(x, horizontalCuts[i] - horizontalCuts[i - 1]);}for (int i = 1; i < n; ++i) {y = Math.max(y, verticalCuts[i] - verticalCuts[i - 1]);}return (int) ((x * y) % mod);}
}

代码中使用了动态规划的思想,将原问题分解为子问题来求解。首先,对水平和垂直切割线进行排序,然后分别计算每一行和每一列的最长距离。接着,将矩形的宽度和高度减去最长的距离,得到剩余的宽度和高度。最后,取剩余宽度和高度中的最大值,即为路径的长度。

在代码实现中,使用了一个辅助函数dp来计算子问题的最优解。首先初始化两个dp数组,分别表示每一行和每一列的最长距离。然后遍历每一行和每一列,计算当前行或列的最长距离,并更新dp数组。最后返回路径的长度。

这个算法的时间复杂度为O(m*n),其中m和n分别为水平切割线和垂直切割线的数量。由于该算法只需要遍历一次切割线,因此时间复杂度可以进一步优化为O(min(m,n))。

GO

func maxArea(h int, w int, horizontalCuts []int, verticalCuts []int) int {horizontalCuts = append(horizontalCuts, []int{0, h}...)verticalCuts = append(verticalCuts, []int{0, w}...)sort.Ints(horizontalCuts)sort.Ints(verticalCuts)x, y := 0, 0const mod int = 1e9 + 7for i := 1; i < len(horizontalCuts); i++ {x = max(x, horizontalCuts[i]-horizontalCuts[i-1])}for i := 1; i < len(verticalCuts); i++ {y = max(y, verticalCuts[i]-verticalCuts[i-1])}return (x * y) % mod
}func max(a, b int) int {if a > b {return a}return b
}

RUST

impl Solution {pub fn max_area(h: i32, w: i32, mut horizontal_cuts: Vec<i32>, mut vertical_cuts: Vec<i32>) -> i32 {const MOD: i64 = 1_000_000_007;horizontal_cuts.sort();vertical_cuts.sort();let m = horizontal_cuts.len();let n = vertical_cuts.len();let mut x = i64::max(horizontal_cuts[0] as i64, h as i64 - horizontal_cuts[m - 1] as i64);let mut y = i64::max(vertical_cuts[0] as i64, w as i64 - vertical_cuts[n - 1] as i64);for i in 1..m {x = i64::max(x, horizontal_cuts[i] as i64 - horizontal_cuts[i - 1] as i64);}for i in 1..n {y = i64::max(y, vertical_cuts[i] as i64 - vertical_cuts[i - 1] as i64);}((x * y) % MOD) as i32}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/121669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGLM推出第三代基座大模型在论文阅读、文档摘要和财报分析等方面提升超过50%推理成本降低一半...

“ 智谱AI发布了第三代基座大模型ChatGLM3&#xff0c;在模型性能、功能支持、开源序列等方面进行了全面升级。ChatGLM3在语义、数学、推理、代码、知识等不同角度的数据集上测评显示&#xff0c;具有在10B以下的基础模型中最强的性能。同时&#xff0c;ChatGLM3还支持多模态理…

Ubuntu 22.04 开机闪logo后卡在/dev/sda3: clean

环境 Vmware 17.0.0&#xff0c;CPU 2&#xff0c;内存4G&#xff0c;硬盘50G Ubuntu 22.04 问题描述 开机 --> 显示两行代码 --> 显示ubuntu logo --> 左上显示两个代码卡住不动 原因分析 1、网上大多说显卡驱动&#xff0c;最近没安装相关软件&#xff0c;也没…

Xilinx MicroBlaze定时器中断无法返回主函数问题解决

最近在使用Xilinx 7系列FPGA XC7A100T时&#xff0c;运行MicroBlaze软核处理器&#xff0c;添加了AXI TIMER IP核&#xff0c;并使能定时器溢出中断&#xff0c;发现定时器触发中断后&#xff0c;无法返回主函数的问题&#xff0c;最后发现修改编译器优化等级就正常了。 FPGA型…

VirtualBox 安装 麒麟Linux

为了验证Oracle EM是否可以管理麒麟OS和其上的Oracle数据库&#xff0c;今天试着在VirtualBox上装了麒麟Linux&#xff0c;也就是银河麒麟。整个过程比较顺畅。 选定ISO文件后&#xff0c;操作系统自动识别为Red Hat。勾选“跳过自动安装”&#xff1a; 内存和CPU选的默认值&…

Qt重定向QDebug,Qt/C++开源作品39-日志输出增强版V2022

Qt重定向QDebug&#xff0c;自定义一个简易的日志管理类 Chapter1 Qt重定向QDebug&#xff0c;自定义一个简易的日志管理类0.前言1.最简单的操作运行结果2.实现一个简易的日志管理类 Chapter2 Qt::Qt Log日志模块Qt Log日志模块官方解释官方Demo思路 Chapter3 QT日志模块的个性…

ssm164学院学生论坛的设计与实现+vue

项目名称&#xff1a;ssm164学院学生论坛的设计与实现vue 点击这里进入源码目录 声明&#xff1a; 适用范围&#xff1a; 本文档适用于广泛的学术和教育用途&#xff0c;包括但不限于个人学习、毕业设计和课程设计。免责声明&#xff1a; 特此声明&#xff0c;本文仅供参考学…

C# 图解教程 第5版 —— 第12章 枚举

文章目录 12.1 枚举12.1.1 设置底层类型和显式值12.1.2 隐式成员编号 12.2 位标志12.2.1 Flags 特性12.2.2 使用位标志的示例&#xff08;*&#xff09; 12.3 关于枚举的更多内容 12.1 枚举 枚举是值类型。只有一种类型的成员&#xff1a;命名的整数值常量。 每个枚举成员都被…

学习Java应该关注哪些网站?

前言 下面是我总结的一些不错的网站&#xff0c;可以收藏看一下哈~希望对你有帮助 一、入门教程类 主要是教程性质的网站&#xff0c;主要是新手学习参考以及相关知识的内容参考 1、菜鸟教程&#xff08;https://www.runoob.com&#xff09; 2、Java学习笔记&#xff08;http…

PostGreSQL模式schema

问题引入 之前在做数据库设计时&#xff0c;经常会忽略schema模式&#xff0c;直接在数据库下的public模式下建立各类数据表。如果数据表命名不够规范&#xff0c;后期寻找某张表时就会比较麻烦。通过 所幸&#xff0c;PostgreSQL 的模式schema管理&#xff0c;可以对这个问题…

VTK OrientationMarker 方向 三维坐标系 相机坐标轴 自定义坐标轴

本文 以 Python 语言开发 我们在做三维软件开发时&#xff0c;经常会用到相机坐标轴&#xff0c;来指示当前空间位置&#xff1b; 坐标轴效果&#xff1a; 相机方向坐标轴 Cube 正方体坐标轴 自定义坐标轴&#xff1a; Code&#xff1a; Axes def main():colors vtkNamedC…

(四)库存超卖案例实战——优化redis分布式锁

前言 在上一节内容中&#xff0c;我们已经实现了使用redis分布式锁解决商品“超卖”的问题&#xff0c;本节内容是对redis分布式锁的优化。在上一节的redis分布式锁中&#xff0c;我们的锁有俩个可以优化的问题。第一&#xff0c;锁需要实现可重入&#xff0c;同一个线程不用重…

归结原理、归结演绎推理

主要内容 归结演绎推理范式子句与子句集将谓词公式转化为子句集命题逻辑鲁宾逊归结原理 归结演绎推理 定理证明的实质是对前提P和结论Q证明P →Q的永真性应用反证法&#xff0c;欲证明P →Q&#xff0c;只要证明 P∧~Q 等价于 F鲁宾逊归结原理对机械化推理有重大突破鲁宾逊归…

XJ+Nreal 高精度地图+Nreal眼镜SDK到发布APK至眼镜中

仅支持Anroid平台 Nreal套装自带的计算单元&#xff0c;其实也是⼀个没有显示器的Android设备 新建unity⼯程&#xff0c;将⼯程切换Android平台。 正在上传…重新上传取消正在上传…重新上传取消 Cloud XDK Unity User Manual for Nreal ARGlasses 该XDK是针对 NReal AR 眼镜…

网络基础-4

链路聚合技术 根据灵活性地增加网络设备之间的带宽供给增强网络设备之间连接的可靠性节约成本 链路聚合 是将两个或更多数据信道结合成一个单个的信道&#xff0c;该信道以一个单个的更高带宽的逻辑链路出现。链路聚合一般用来连接一个或多个带宽需求大的设备&#xff0c;例…

Vue $nextTick

我们用一个例子来说明$nextTick的作用&#xff1a; 我们用一个变量showIpt来控制input框的显示和隐藏&#xff0c;默认是隐藏。 我们点击一个按钮后显示这个输入框的同时&#xff0c;input还要自动获取焦点。 但是我们点击按钮过后并没有生效。 为什么&#xff1f;this.show…

【PG】PostgreSQL客户端认证pg_hba.conf文件

目录 文件格式 连接类型(TYPE) 数据库&#xff08;database&#xff09; 用户(user) 连接地址&#xff08;address&#xff09; 格式 IPv4 IPv6 字符 主机名 主机名后缀 IP-address/IP-mask auth-method trust reject scram-sha-256 md5 password gss sspi …

23种设计模式【创建型模式】详细介绍之【建造者模式】

建造者模式&#xff1a;构建复杂对象的精妙设计 设计模式的分类和应用场景总结建造者模式&#xff1a;构建复杂对象的精妙设计建造者模式的核心思想建造者模式的参与者Java示例&#xff1a;建造者模式 设计模式的分类和应用场景总结 可以查看专栏设计模式&#xff1a;设计模式 …

STM32中除零运算,为何程序不崩溃?

在 C 语言中&#xff0c;除零运算会导致异常吗&#xff1f; 在 C 语言中&#xff0c;当一个数除以零时&#xff0c;会导致除法运算错误&#xff0c;通常表现为“除以零”错误或被称为“浮点异常”&#xff08;floating-point exception&#xff09;。 对于整数除法&#xff0c…

RHCE---正则表达式

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 一. 文本搜索工具 grep是linux中一种强大的文件搜索过滤工具&#xff0c;可以按照正 则表达式检索文件内容&#xff0c;并把匹配的结果显示到屏幕上 &#xff08;匹配的内容会标红&#x…

设计模式(15)组合模式

一、介绍&#xff1a; 1、定义&#xff1a;组合多个对象形成树形结构以表示“整体-部分”的关系的层次结构。组合模式对叶子节点和容器节点的处理具有一致性&#xff0c;又称为整体-部分模式。 2、优缺点&#xff1a; 优点&#xff1a; &#xff08;1&#xff09;高层模块调…