2026-03-11:最长平衡子数组Ⅰ。用go语言,给定一个整数数组 nums。把数组中任意一段连续且非空的元素称为子数组;如果

举报
福大大架构师每日一题 发表于 2026/03/11 06:44:12 2026/03/11
【摘要】 2026-03-11:最长平衡子数组Ⅰ。用go语言,给定一个整数数组 nums。把数组中任意一段连续且非空的元素称为子数组;如果把子数组里的元素去重后,偶数的个数与奇数的个数相等,就把该子数组称为“平衡子数组”。请找出数组中最长的平衡子数组,并返回它的长度。1 <= nums.length <= 1500。1 <= nums[i] <= 100000。输入: nums = [2,5,4,3]...

2026-03-11:最长平衡子数组Ⅰ。用go语言,给定一个整数数组 nums。把数组中任意一段连续且非空的元素称为子数组;如果把子数组里的元素去重后,偶数的个数与奇数的个数相等,就把该子数组称为“平衡子数组”。请找出数组中最长的平衡子数组,并返回它的长度。

1 <= nums.length <= 1500。

1 <= nums[i] <= 100000。

输入: nums = [2,5,4,3]。

输出: 4。

解释:

最长平衡子数组是 [2, 5, 4, 3]。

它有 2 个不同的偶数 [2, 4] 和 2 个不同的奇数 [5, 3]。因此,答案是 4 。

题目来自力扣3719。

一、代码执行过程详细拆解

我们以输入 nums = [2, 5, 4, 3] 为例,分步拆解 longestBalanced 函数的执行逻辑:

步骤1:初始化全局最大值

函数首先定义 maxLen = 0,用于记录找到的最长平衡子数组长度,初始值为0。

步骤2:外层循环确定子数组起始位置

外层 for 循环(i 从0到len(nums)-1)遍历数组的每一个位置,作为子数组的起始下标

  • i=0 时,子数组起始于第0个元素(值为2);
  • i=1 时,子数组起始于第1个元素(值为5);
  • i=2 时,子数组起始于第2个元素(值为4);
  • i=3 时,子数组起始于第3个元素(值为3)。

步骤3:内层循环扩展子数组结束位置

对于每一个起始下标 i,内层 for 循环(ji到len(nums)-1)遍历数组,作为子数组的结束下标,并实时统计子数组的奇偶特征:

  1. 初始化统计容器:每次外层循环(换起始位置)时,都会新建两个空字典:
    • odd:键为子数组中的奇数,值为该奇数出现的次数(仅记录“存在性”,次数无实际意义);
    • even:键为子数组中的偶数,值为该偶数出现的次数(同理,次数无实际意义)。
  2. 遍历并更新统计:内层循环每遍历一个元素 nums[j]
    • 判断奇偶:通过 nums[j]&1 == 1 判断(按位与1,结果为1则是奇数,0则是偶数);
    • 更新字典:奇数则在 odd 中记录该数(次数+1),偶数则在 even 中记录该数(次数+1)。
  3. 判断是否平衡并更新最大值:每次更新字典后,检查 oddeven键的数量(即去重后的奇偶数量)是否相等:
    • 若相等:计算当前子数组长度 j-i+1,如果比 maxLen 大,则更新 maxLen
    • 若不相等:不做处理,继续内层循环。

步骤4:以示例输入具体走一遍逻辑

输入 nums = [2,5,4,3]

  • i=0(起始为2)
    • j=0(子数组[2]):even={2:1},odd={} → len(even)=1,len(odd)=0 → 不平衡;
    • j=1(子数组[2,5]):even={2:1},odd={5:1} → len=1:1 → 平衡,maxLen=2;
    • j=2(子数组[2,5,4]):even={2:1,4:1},odd={5:1} → len=2:1 → 不平衡;
    • j=3(子数组[2,5,4,3]):even={2:1,4:1},odd={5:1,3:1} → len=2:2 → 平衡,maxLen=4;
  • i=1(起始为5)
    • j=1([5]):odd={5:1},even={} → 不平衡;
    • j=2([5,4]):odd={5:1},even={4:1} → 平衡,长度2(小于当前maxLen=4,不更新);
    • j=3([5,4,3]):odd={5:1,3:1},even={4:1} → 不平衡;
  • i=2(起始为4)
    • j=2([4]):even={4:1},odd={} → 不平衡;
    • j=3([4,3]):even={4:1},odd={3:1} → 平衡,长度2(不更新);
  • i=3(起始为3)
    • j=3([3]):odd={3:1},even={} → 不平衡;

最终 maxLen=4,函数返回4,与示例输出一致。

二、时间复杂度与空间复杂度分析

1. 时间复杂度

  • 外层循环:遍历数组的每个元素作为起始位置,共 n 次(n 为数组长度);
  • 内层循环:对于每个起始位置 i,内层循环最多遍历 n-i 次,总次数为 n + (n-1) + (n-2) + ... + 1 = n*(n+1)/2,即 O(n²)
  • 内层循环的操作(判断奇偶、更新字典、判断长度)均为 O(1) 时间(字典的增/查操作平均时间复杂度为 O(1));
  • 综上,总的时间复杂度为 O(n²)(n≤1500时,n²=225万,计算量可接受)。

2. 额外空间复杂度

  • 每次外层循环会新建两个字典 oddeven,字典的最大大小取决于子数组中去重后的奇偶数量:
    • 最坏情况下(子数组包含所有元素,且所有数都不重复),字典的键数量最多为 n(如数组全为不同奇数/偶数);
    • 但由于每次外层循环结束后,该次循环的字典会被销毁,因此额外空间复杂度为 O(n)(仅需存储当前子数组的奇偶统计字典)。

总结

  1. 核心逻辑:通过双层循环枚举所有可能的子数组,实时统计子数组内去重后的奇偶数量,判断是否平衡并更新最长长度;
  2. 时间复杂度:O(n²)(n为数组长度),双层循环是主要时间开销;
  3. 空间复杂度:O(n),额外空间主要用于存储当前子数组的奇偶统计字典。

Go完整代码如下:

package main

import (
	"fmt"
)

func longestBalanced(nums []int) int {
	maxLen := 0

	for i := 0; i < len(nums); i++ {
		odd := make(map[int]int)
		even := make(map[int]int)

		for j := i; j < len(nums); j++ {
			if nums[j]&1 == 1 {
				odd[nums[j]]++
			} else {
				even[nums[j]]++
			}

			if len(odd) == len(even) {
				if j-i+1 > maxLen {
					maxLen = j - i + 1
				}
			}
		}
	}

	return maxLen
}

func main() {
	nums := []int{2, 5, 4, 3}
	result := longestBalanced(nums)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def longest_balanced(nums):
    max_len = 0
    
    for i in range(len(nums)):
        odd = {}
        even = {}
        
        for j in range(i, len(nums)):
            if nums[j] & 1:  # 判断是否为奇数
                odd[nums[j]] = odd.get(nums[j], 0) + 1
            else:
                even[nums[j]] = even.get(nums[j], 0) + 1
            
            if len(odd) == len(even):
                if j - i + 1 > max_len:
                    max_len = j - i + 1
    
    return max_len

def main():
    nums = [2, 5, 4, 3]
    result = longest_balanced(nums)
    print(result)

if __name__ == "__main__":
    main()

在这里插入图片描述

C++完整代码如下:

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int longestBalanced(vector<int>& nums) {
    int maxLen = 0;

    for (int i = 0; i < nums.size(); i++) {
        unordered_map<int, int> odd;
        unordered_map<int, int> even;

        for (int j = i; j < nums.size(); j++) {
            if (nums[j] & 1) {  // 判断是否为奇数
                odd[nums[j]]++;
            } else {
                even[nums[j]]++;
            }

            if (odd.size() == even.size()) {
                if (j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                }
            }
        }
    }

    return maxLen;
}

int main() {
    vector<int> nums = {2, 5, 4, 3};
    int result = longestBalanced(nums);
    cout << result << endl;
    return 0;
}

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。