【LeetCode 每日一题】2975. 移除栅栏得到的正方形田地的最大面积

Problem: 2975. 移除栅栏得到的正方形田地的最大面积

文章目录

  • 整体思路
      • [1. 核心问题](#1. 核心问题)
      • [2. 算法逻辑](#2. 算法逻辑)
  • 完整代码
  • 时空复杂度
      • [1. 时间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)](#1. 时间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2))
      • [2. 空间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)](#2. 空间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2))

整体思路

1. 核心问题

我们需要在一个 m × n m \times n m×n 的矩形田地中,选择水平栅栏(hFences)和垂直栅栏(vFences),构建一个正方形区域。

  • 田地的边界分别是水平线 1m,垂直线 1n
  • 输入给定的 hFencesvFences 是中间的栅栏,边界栅栏默认存在。
  • 目标:找到可能形成的正方形的最大面积。如果无法形成,返回 -1。

2. 算法逻辑

正方形的边长取决于两个栅栏之间的间距

  • 如果在水平方向上存在两个栅栏,它们之间的距离为 L L L。
  • 如果在垂直方向上也存在两个栅栏,它们之间的距离也为 L L L。
  • 那么这两个间距组合起来就能围成一个边长为 L L L 的正方形。

步骤

  1. 预处理栅栏 :对于水平和垂直方向,都要把边界1mn)加入到给定的栅栏数组中。
  2. 计算所有可能的间距
    • 分别计算水平方向所有可能的间距集合 hSet
    • 分别计算垂直方向所有可能的间距集合 vSet
    • 这里使用双重循环遍历排序后的栅栏数组,计算任意两根栅栏之间的距离 fences[j] - fences[i]
  3. 寻找交集最大值
    • 遍历其中一个集合(如 hSet),检查其中的间距是否也存在于另一个集合 vSet 中。
    • 如果是,说明这个长度 L L L 既可以是宽也可以是高,能构成正方形。更新最大边长 ans
  4. 计算结果 :如果找到了合法的正方形(ans > 0),返回面积并取模;否则返回 -1。

完整代码

java 复制代码
import java.util.*;

class Solution {
    final int MOD = 1_000_000_007;

    public int maximizeSquareArea(int m, int n, int[] hFences, int[] vFences) {
        // 1. 获取水平方向所有可能的间距集合
        // m 是水平方向的边界坐标 (行数)
        Set<Integer> hSet = gapSet(hFences, m);
        
        // 2. 获取垂直方向所有可能的间距集合
        // n 是垂直方向的边界坐标 (列数)
        Set<Integer> vSet = gapSet(vFences, n);
        
        // 记录最大合法边长
        int ans = 0;
        
        // 3. 寻找两个集合的交集中的最大值
        // 遍历水平间距集合
        for (int x : hSet) {
            // 如果垂直方向也有相同的间距 x
            if (vSet.contains(x)) {
                // 更新最大边长
                ans = Math.max(ans, x);
            }
        }
        
        // 4. 计算面积并返回
        if (ans == 0) {
            return -1; // 没有找到任何匹配的间距(实际上通常至少有 min(m-1, n-1),除非输入限制特殊)
        }
        
        // 面积可能很大,需要转换成 long 进行乘法,然后取模
        return (int)((long) ans * ans % MOD);
    }

    // 辅助方法:计算所有可能的栅栏间距
    // fences: 内部栅栏坐标数组
    // boundary: 边界坐标 (对应 m 或 n)
    private Set<Integer> gapSet(int[] fences, int boundary) {
        int len = fences.length;
        
        // 创建新数组,长度比原数组多 2,用于存放边界 1 和 boundary
        // fences 本身是引用传递,为了不修改原数组并加入新元素,使用 copyOf
        fences = Arrays.copyOf(fences, len + 2);
        
        // 添加边界栅栏
        fences[len] = 1;
        fences[len + 1] = boundary;
        
        // 排序,方便从小到大计算间距
        Arrays.sort(fences);
        
        // 使用 HashSet 存储所有可能的间距,自动去重
        Set<Integer> st = new HashSet<>();
        
        // 双重循环枚举任意两根栅栏
        for (int i = 0; i < fences.length; i++) {
            for (int j = i + 1; j < fences.length; j++) {
                // 计算间距并加入集合
                st.add(fences[j] - fences[i]);
            }
        }
        return st;
    }
}

时空复杂度

假设 hFences 长度为 H H H,vFences 长度为 V V V。

1. 时间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)

  • gapSet 函数
    • 排序: O ( H log ⁡ H ) O(H \log H) O(HlogH)。
    • 双重循环枚举所有间距:这是一个组合问题,次数为 C ( H , 2 ) ≈ O ( H 2 ) C(H, 2) \approx O(H^2) C(H,2)≈O(H2)。
    • HashSet 插入操作平均 O ( 1 ) O(1) O(1)。
    • 因此,处理水平栅栏耗时 O ( H 2 ) O(H^2) O(H2),处理垂直栅栏耗时 O ( V 2 ) O(V^2) O(V2)。
  • 交集查找
    • 遍历 hSet,其大小最多为 O ( H 2 ) O(H^2) O(H2)。
    • vSet 中查找,平均 O ( 1 ) O(1) O(1)。
    • 这部分耗时 O ( H 2 ) O(H^2) O(H2)。
  • 总计 : O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)。
    • 注意:如果 H H H 或 V V V 很大(例如 10 5 10^5 105),这个 O ( N 2 ) O(N^2) O(N2) 算法会超时。但根据题目(LeetCode 2975)的数据约束,栅栏数量通常较小(如 600),允许 O ( N 2 ) O(N^2) O(N2) 通过。

2. 空间复杂度: O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)

  • 计算依据
    • 我们需要两个 HashSet 来存储所有可能的间距。
    • 水平方向最多有 ( H + 2 ) ( H + 1 ) 2 \frac{(H+2)(H+1)}{2} 2(H+2)(H+1) 个间距,即 O ( H 2 ) O(H^2) O(H2)。
    • 垂直方向最多有 O ( V 2 ) O(V^2) O(V2) 个间距。
  • 结论 : O ( H 2 + V 2 ) O(H^2 + V^2) O(H2+V2)。

参考灵神

相关推荐
无敌昊哥战神9 小时前
深入理解 C 语言:巧妙利用“0地址”手写 offsetof 宏与内存对齐机制
c语言·数据结构·算法
小白菜又菜9 小时前
Leetcode 2075. Decode the Slanted Ciphertext
算法·leetcode·职场和发展
Proxy_ZZ09 小时前
用Matlab绘制BER曲线对比SPA与Min-Sum性能
人工智能·算法·机器学习
黎阳之光9 小时前
黎阳之光:以视频孪生领跑全球,赋能数字孪生水利智能监测新征程
大数据·人工智能·算法·安全·数字孪生
小李子呢021110 小时前
前端八股6---v-model双向绑定
前端·javascript·算法
前端大波10 小时前
前端面试通关包(2026版,完整版)
前端·面试·职场和发展
2301_8227032011 小时前
Flutter 框架跨平台鸿蒙开发 - 创意声音合成器应用
算法·flutter·华为·harmonyos·鸿蒙
zhaoshuzhaoshu11 小时前
人工智能(AI)发展史:详细里程碑
人工智能·职场和发展
cmpxr_11 小时前
【C】数组名、函数名的特殊
c语言·算法
KAU的云实验台11 小时前
【算法精解】AIR期刊算法IAGWO:引入速度概念与逆多元二次权重,可应对高维/工程问题(附Matlab源码)
开发语言·算法·matlab