
2026-03-07:最长的平衡子串Ⅰ。用go语言,给定一个只含小写字母的字符串 s。我们把任意连续且非空的字符区间称为一个片段;当该片段内每一种不同字母出现的频次都相同,就称它为“均衡片段”。请找出 s 中最长的均衡片段,并返回它的长度。
1 <= s.length <= 1000。
s 仅由小写英文字母组成。
输入: s = "abbac"。
输出: 4。
解释:
最长的平衡子串是 "abba",因为不同字符 'a' 和 'b' 都恰好出现了 2 次。
题目来自力扣3713。
整个算法采用暴力枚举所有子串 + 验证是否为均衡片段的思路,具体步骤如下:
s的长度n,用于后续遍历边界控制;res为0,用于记录找到的最长均衡片段的长度(初始为0表示未找到任何有效片段)。外层循环遍历字符串的每一个位置i(从0到n-1),将i作为子串的起始索引:
i,首先创建一个长度为26的数组cnt(对应26个小写字母),初始值全为0,用于统计当前子串中每个字母的出现次数;cnt数组会在每次更换起点i时重新初始化,保证统计的是“以i为起点的子串”的字母频次。内层循环遍历从起点i到字符串末尾的每一个位置j(从i到n-1),将j作为子串的结束索引:
j的字符s[j],转换为0-25的索引(c = s[j] - 'a',比如'a'对应0,'b'对应1);cnt[c]加1,记录该字母在i~j子串中又出现了一次。flag为true(假设当前子串是均衡的);cnt数组的所有26个元素(对应所有小写字母):x(某字母的出现次数),如果x > 0(说明该字母出现在当前子串中),且x != cnt[c](当前新增字母的出现次数),则说明子串中存在出现次数不同的字母,将flag设为false并跳出遍历;flag仍为true(当前i~j子串是均衡片段),且子串长度j-i+1大于当前记录的res,则更新res为j-i+1。s = "abbac"为例,模拟执行过程输入字符串索引:0:a,1:b,2:b,3:a,4:c
i=0(起点为a):j=0(子串"a"):cnt[0]=1,其他为0。遍历cnt,只有cnt[0]=1非零,满足“所有非零频次相同”,res更新为1;j=1(子串"ab"):cnt[0]=1,cnt[1]=1。所有非零频次都是1,满足条件,res更新为2;j=2(子串"abb"):cnt[0]=1,cnt[1]=2。cnt[0]≠cnt[1],不满足;j=3(子串"abba"):cnt[0]=2,cnt[1]=2。所有非零频次都是2,满足条件,res更新为4;j=4(子串"abbac"):cnt[0]=2,cnt[1]=2,cnt[2]=1。cnt[2]≠2,不满足;i=1(起点为b):i=2、i=3、i=4时:遍历完所有起点和终点后,返回res即为最长均衡片段的长度。
n次(n为字符串长度);i,最多遍历n-i次,整体为O(n²);O(1);O(n² × 26) = O(n²)(26是常数,可忽略)。i对应的cnt数组:长度固定为26,占用O(26) = O(1)的空间;O(1)的固定空间;O(1)(无论字符串多长,空间消耗都是固定的)。O(n²)(n为字符串长度),额外空间复杂度为O(1)(仅使用固定长度的数组和少量变量)。.
package main
import (
"fmt"
)
func longestBalanced(s string)int {
n := len(s)
res := 0
for i := 0; i < n; i++ {
cnt := make([]int, 26)
for j := i; j < n; j++ {
c := s[j] - 'a'
cnt[c]++
flag := true
for _, x := range cnt {
if x > 0 && x != cnt[c] {
flag = false
break
}
}
if flag && (j-i+1) > res {
res = j - i + 1
}
}
}
return res
}
func main() {
s := "abbac"
result := longestBalanced(s)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
def longest_balanced(s: str) -> int:
"""
找到最长的平衡子串的长度
平衡子串定义为:子串中出现的所有字符的出现次数相同
Args:
s: 输入字符串
Returns:
最长平衡子串的长度
"""
n = len(s)
res = 0
# 遍历所有可能的子串起始位置
for i in range(n):
# 统计当前子串中每个字符出现的次数
cnt = [0] * 26
# 扩展子串的结束位置
for j in range(i, n):
c = ord(s[j]) - ord('a') # 将字符转换为索引(0-25)
cnt[c] += 1
# 检查当前子串是否平衡
flag = True
for x in cnt:
if x > 0 and x != cnt[c]:
flag = False
break
# 如果是平衡子串且长度更长,更新结果
if flag and (j - i + 1) > res:
res = j - i + 1
return res
def main():
s = "abbac"
result = longest_balanced(s)
print(result)
if __name__ == "__main__":
main()
.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
/**
* 找到最长的平衡子串的长度
* 平衡子串定义为:子串中出现的所有字符的出现次数相同
*
* @param s 输入字符串
* @return 最长平衡子串的长度
*/
int longestBalanced(conststring& s) {
int n = s.length();
int res = 0;
// 遍历所有可能的子串起始位置
for (int i = 0; i < n; i++) {
// 统计当前子串中每个字符出现的次数
vector<int> cnt(26, 0);
// 扩展子串的结束位置
for (int j = i; j < n; j++) {
int c = s[j] - 'a'; // 将字符转换为索引(0-25)
cnt[c]++;
// 检查当前子串是否平衡
bool flag = true;
for (int x : cnt) {
if (x > 0 && x != cnt[c]) {
flag = false;
break;
}
}
// 如果是平衡子串且长度更长,更新结果
if (flag && (j - i + 1) > res) {
res = j - i + 1;
}
}
}
return res;
}
int main() {
string s = "abbac";
int result = longestBalanced(s);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
·