3714.最长的平衡子串 II:前缀和(一二三分类)
【LetMeFly】3714.最长的平衡子串 II:前缀和(一二三分类)
力扣题目链接:https://leetcode.cn/problems/longest-balanced-substring-ii/
给你一个只包含字符 'a'、'b' 和 'c' 的字符串 s。
如果一个 子串 中所有 不同 字符出现的次数都 相同,则称该子串为 平衡 子串。
请返回 s 的 最长平衡子串 的 长度 。
子串 是字符串中连续的、非空 的字符序列。
示例 1:
输入: s = "abbac"
输出: 4
解释:
最长的平衡子串是 "abba",因为不同字符 'a' 和 'b' 都恰好出现了 2 次。
示例 2:
输入: s = "aabcc"
输出: 3
解释:
最长的平衡子串是 "abc",因为不同字符 'a'、'b' 和 'c' 都恰好出现了 1 次。
示例 3:
输入: s = "aba"
输出: 2
解释:
最长的平衡子串之一是 "ab",因为不同字符 'a' 和 'b' 都恰好出现了 1 次。另一个最长的平衡子串是 "ba"。
提示:
1 <= s.length <= 105s仅包含字符'a'、'b'和'c'。
解题方法:前缀和
这是一道
屎山代码题,很多人在这道题写了好大一*。
具体方法
依据平衡字符串中所含字符的种类数分别想办法求解。
如果平衡字符串中只有一种字符
问题就变成了“求一个字符串中最长连续子串”。
使用一个变量记录上一个字符是什么,使用一个变量记录当前的连续相同字符数;遍历字符串并依据当前字符是否和上一个字符相同进行操作。
如果平衡字符串中恰好有两种字符
问题就变成了525. 连续数组:只有0、1的字符串求01数量相同的最大子串。
可以使用一个哈希表记录1比0多出现次数: 第一次出现该diff的下标。
例如遍历到下标$3$时1比0多出现了$5$次,遍历到下标$20$时1比0又多出现了$5$次,则说明下标$4$到下标$20$的子串0和1出现次数相等。
如果平衡字符串中包含三种字符
同样适用前缀和记录abc三种字符每种分别出现了多少次。(假设$cnt_a[i]$代表遍历到下标$i$为止a出现的次数)
如果下标$i+1$到$j$的子串是平衡字符串需要满足什么?需要满足子串中a出现次数和b出现次数相等、a出现次数和c出现次数相等:
- $cnt_a[j] - cnt_a[i] = cnt_b[j] - cnt_b[i]$
- $cnt_a[j] - cnt_a[i] = cnt_c[j] - cnt_c[i]$
移项将相同下标放到等号一边,可得:
- $cnt_a[j] - cnt_b[j] = cnt_a[i] - cnt_b[i]$
- $cnt_a[j] - cnt_c[j] = cnt_a[i] - cnt_c[i]$
说明下标$i$和下标$j$的$cnt_a-cnt_b$相等且$cnt_a-cnt_c$相等。
哦吼,那么我们把包含两种字符串时候的key $1次数-0次数$ 修改为 $(a次数-b次数, a次数-c次数)$这么一个数对不就好了吗。
时空复杂度分析
- 时间复杂度$O(len(s))$
- 空间复杂度$O(len(s))$
AC代码
C++
1 | |
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源