【LeetCode 每日一题】3719. 最长平衡子数组 I ——暴力枚举

Problem: 3719. 最长平衡子数组 I

文章目录

  • [1. 整体思路](#1. 整体思路)
  • [2. 完整代码](#2. 完整代码)
  • [3. 时空复杂度](#3. 时空复杂度)
      • [时间复杂度: O ( N 2 ) O(N^2) O(N2)](#时间复杂度: O ( N 2 ) O(N^2) O(N2))
      • [空间复杂度: O ( N ) O(N) O(N)](#空间复杂度: O ( N ) O(N) O(N))

1. 整体思路

核心问题

在一个数组 nums 中,找到一个最长的连续子数组 nums[i...j],使得该子数组中奇数的种类数偶数的种类数 相等。

例如:[1, 2, 1, 4]

  • 子数组 [1, 2, 1]:奇数种类 {1} (1种),偶数种类 {2} (1种)。相等,长度 3。
  • 子数组 [1, 2, 1, 4]:奇数种类 {1} (1种),偶数种类 {2, 4} (2种)。不相等。

算法逻辑

该解法使用了暴力枚举所有子数组的方法。

  1. 双重循环遍历

    • 外层循环 i 从 0 到 n-1,作为子数组的起始位置
    • 内层循环 jin-1,作为子数组的结束位置
  2. 维护状态

    • 对于每个固定的起始位置 i,随着 j 向右移动,我们需要实时知道当前窗口 [i, j] 内奇数和偶数的种类数。
    • 使用两个哈希表 HashMap<Integer, Integer>
      • odd:存储当前子数组中出现的奇数及其频次(其实只存频次是为了统计种类数 size())。
      • even:存储当前子数组中出现的偶数及其频次。
  3. 判断与更新

    • 每当 j 移动一步,将 nums[j] 加入对应的哈希表。
    • 检查 odd.size() == even.size()。如果相等,说明当前子数组是"平衡"的。
    • 更新全局最大长度 ans

2. 完整代码

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

class Solution {
    public int longestBalanced(int[] nums) {
        int n = nums.length;
        // 记录最长平衡子数组的长度,初始为 0
        int ans = 0;

        // 外层循环:枚举所有可能的子数组起始位置 i
        for (int i = 0; i < n; i++) {
            // 对于每个起始位置 i,我们需要重新统计奇偶数的种类
            // 使用两个哈希表来记录窗口内的元素
            // key: 数值, value: 出现次数 (本题逻辑只关心 key 是否存在,value 其实可以省略或者用 HashSet)
            HashMap<Integer, Integer> odd = new HashMap<>();
            HashMap<Integer, Integer> even = new HashMap<>();
            
            // 内层循环:枚举所有可能的子数组结束位置 j
            // 随着 j 增加,窗口 [i, j] 向右扩展
            for (int j = i; j < n; j++) {
                // 判断当前元素 nums[j] 是奇数还是偶数,并加入对应的集合
                if (nums[j] % 2 == 0) {
                    // 偶数
                    even.put(nums[j], even.getOrDefault(nums[j], 0) + 1);
                } else {
                    // 奇数
                    odd.put(nums[j], odd.getOrDefault(nums[j], 0) + 1);
                }
                
                // 核心判断条件:奇数种类数 == 偶数种类数
                // 注意:这里比较的是 size(),即不同数值的个数,而不是总个数
                if (odd.size() == even.size()) {
                    // 更新最大长度
                    ans = Math.max(ans, j - i + 1);
                }
            }
        }
        
        return ans;
    }
}

3. 时空复杂度

假设数组 nums 的长度为 N N N。

时间复杂度: O ( N 2 ) O(N^2) O(N2)

  • 计算依据
    • 代码包含两层嵌套循环。
    • 外层循环执行 N N N 次。
    • 内层循环平均执行 N / 2 N/2 N/2 次。
    • 哈希表的操作(插入、查询 size)平均时间复杂度为 O ( 1 ) O(1) O(1)。
    • 总操作次数约为 N ( N + 1 ) 2 \frac{N(N+1)}{2} 2N(N+1)。
  • 结论 : O ( N 2 ) O(N^2) O(N2)。
    • 对于 N ≤ 1000 N \le 1000 N≤1000 或 2000 2000 2000 的数据规模,这个解法是可以接受的。但如果 N N N 较大(如 10 5 10^5 105),则会超时。

空间复杂度: O ( N ) O(N) O(N)

  • 计算依据
    • 在最坏情况下(所有元素都不同),两个哈希表可能会存储 O ( N ) O(N) O(N) 个键值对。
    • 虽然哈希表是在循环内部创建的,但每次内层循环都会重新分配空间,最大占用为 O ( N ) O(N) O(N)。
  • 结论 : O ( N ) O(N) O(N)。
相关推荐
羊羊小栈2 分钟前
基于「YOLO目标检测 + 多模态AI分析」的公共场所暴力安全智能检测分析预警系统
人工智能·算法·面试·毕业设计·大作业
土星云SaturnCloud12 分钟前
ResNet-50 图像分类算法在边缘微服务器上的部署与性能评测
服务器·人工智能·算法·边缘计算·resnet-50
Niuguangshuo14 分钟前
文本-音频时间戳对齐:5 个开源工具实测
算法·开源·音视频
Niuguangshuo19 分钟前
论文解读:RNN-Transducer,端到端流式 ASR 的骨架
算法·语音识别
GreenTea30 分钟前
🔥别再用压缩了,Codex、NVIDIA、DeepSeek、Uber 给出 Agent 上下文管理的新答案
前端·后端·算法
All for pursuit.43 分钟前
【矩阵-2】240.搜索二维矩阵 II
数据结构·c++·算法·leetcode
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 209. 长度最小的子数组 | C++ 滑动窗口(毛毛虫算法)经典模板
c++·算法·leetcode
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 28. 找出字符串中第一个匹配项的下标 | C++ 滑动窗口与子串比对
c++·算法·leetcode
GreenTea10 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
Bode_200210 小时前
多资源规划(含生产调度、库存管理及产能规划)的创新优化算法
算法·调度