【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 小时前
【优选算法】(实战体会位运算的逻辑思维)
数据结构·c++·笔记·学习·算法·leetcode·visual studio
Frostnova丶2 小时前
LeetCode 2573. 找出对应 LCP 矩阵的字符串
算法·leetcode·矩阵
承渊政道2 小时前
【优选算法】(实战推演模拟算法的蕴含深意)
数据结构·c++·笔记·学习·算法·leetcode·排序算法
林鸿群3 小时前
实现支持纳秒级精度的时间引擎(C++)
算法·定时引擎
Keep learning!3 小时前
PCA主成分分析学习
学习·算法
专注VB编程开发20年3 小时前
CUDA实现随机切割算法,显卡多线程计算
算法·cuda
2301_788770553 小时前
OJ模拟4
算法
NAGNIP4 小时前
一文搞懂CNN经典架构-AlexNet!
人工智能·算法
2401_878530214 小时前
自定义内存布局控制
开发语言·c++·算法
专注VB编程开发20年4 小时前
PNG、GIF透明游戏角色人物输出一张图片技巧,宽度高度读取
算法