M2943.最大化网格图中正方形空洞的面积
sorting, https://leetcode.cn/problems/maximize-area-of-square-hole-in-grid/
给你两个整数 n 和 m,以及两个整数数组 hBars 和 vBars。网格由 n + 2 条水平线和 m + 2条竖直线组成,形成 1x1 的单元格。网格中的线条从 1 开始编号。
你可以从 hBars 中 删除 一些水平线条,并从 vBars 中删除一些竖直线条。注意,其他线条是固定的,无法删除。
返回一个整数表示移除一些线条(可以不移除任何线条)后,网格中 正方形空洞的最大面积 。
示例 1:

输入: n = 2, m = 1, hBars = [2,3], vBars = [2]
输出: 4
解释:
左侧图片展示了网格的初始状态。水平线是 [1,2,3,4],竖直线是 [1,2,3]。
构造最大正方形空洞的一种方法是移除水平线 2 和竖直线 2。
示例 2:

输入: n = 1, m = 1, hBars = [2], vBars = [2]
输出: 4
解释:
移除水平线 2 和竖直线 2,可以得到最大正方形空洞。
示例 3:

输入: n = 2, m = 3, hBars = [2,3], vBars = [2,4]
输出: 4
解释:
构造最大正方形空洞的一种方法是移除水平线 3 和竖直线 4。
提示:
1 <= n <= 10^91 <= m <= 10^91 <= hBars.length <= 1002 <= hBars[i] <= n + 11 <= vBars.length <= 1002 <= vBars[i] <= m + 1hBars中所有值互不相同。vBars中所有值互不相同。
这个问题可以通过寻找 连续可移除线条的最大长度 来解决。
解题思路
理解“空洞”的形成:
- 网格原本由
的小方格组成。 - 如果我们移除
条连续的水平线(例如线 ),那么在垂直方向上,原本由这些线隔开的单元格就会连通,形成一个高度为 的间隙。 - 同理,移除
条连续的竖直线,会形成一个宽度为 的间隙。
- 网格原本由
正方形的约束:
- 要形成一个边长为
的正方形空洞,我们需要在水平方向上至少有一个长度为 的间隙,且在垂直方向上至少有一个长度为 的间隙。 - 因此,最大正方形的边长
。
- 要形成一个边长为
算法步骤:
- 分别对
hBars和vBars进行排序。 - 在
hBars中找出最长的连续整数序列。假设最长连续长度为maxH,则最大的水平间隙为maxH + 1。 - 在
vBars中找出最长的连续整数序列。假设最长连续长度为maxV,则最大的垂直间隙为maxV + 1。 - 最大正方形边长
。 - 返回
。
- 分别对
Python 代码实现
python
class Solution:
def maximizeSquareHoleArea(self, n: int, m: int, hBars: List[int], vBars: List[int]) -> int:
def get_max_consecutive(bars):
# 1. 排序,以便寻找连续的数字
bars.sort()
max_len = 1
current_len = 1
# 2. 遍历数组寻找最长连续序列
for i in range(1, len(bars)):
if bars[i] == bars[i-1] + 1:
current_len += 1
else:
current_len = 1
if current_len > max_len:
max_len = current_len
# 3. 移除 k 条连续线会产生 k + 1 的跨度
return max_len + 1
# 计算水平和垂直方向的最大跨度
max_h_gap = get_max_consecutive(hBars)
max_v_gap = get_max_consecutive(vBars)
# 正方形的边长受限于较短的那一边
side = min(max_h_gap, max_v_gap)
return side * side复杂度分析
- 时间复杂度:
,其中 是 hBars的长度,是 vBars的长度。主要耗时在排序上(题目中,因此该算法极其高效)。 - 空间复杂度:
或 ,取决于排序算法的具体实现(在 Python 中 sort()通常需要的辅助空间)。