【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)。
相关推荐
寻寻觅觅☆6 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
偷吃的耗子7 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
2013编程爱好者7 小时前
【C++】树的基础
数据结构·二叉树··二叉树的遍历
NEXT067 小时前
二叉搜索树(BST)
前端·数据结构·面试
化学在逃硬闯CS7 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar1238 小时前
C++使用format
开发语言·c++·算法
Gofarlic_OMS8 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
夏鹏今天学习了吗8 小时前
【LeetCode热题100(100/100)】数据流的中位数
算法·leetcode·职场和发展
忙什么果9 小时前
上位机、下位机、FPGA、算法放在哪层合适?
算法·fpga开发
董董灿是个攻城狮9 小时前
AI 视觉连载4:YUV 的图像表示
算法