LeetCode - 字符串 - 1371. 每个元音包含偶数次的最长子字符串

题目 1371. 每个元音包含偶数次的最长子字符串

难度 中等

给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 ‘a’,‘e’,‘i’,‘o’,‘u’ ,在子字符串中都恰好出现了偶数次。

示例1:

输入:s = “eleetminicoworoep”
输出:13
解释:最长子字符串是 “leetminicowor” ,它包含 e,i,o 各 2 个,以及 0 个 a,u

示例2:

输入:s = “leetcodeisgreat”
输出:5
解释:最长子字符串是 “leetc” ,其中包含 2 个 e

示例3:

输入:s = “bcbcbc”
输出:6
解释:这个示例中,字符串 “bcbcbc” 本身就是最长的,因为所有的元音 a,e,i,o,u 都出现了 0 次

解题思路

最直观的方法无非就是枚举所有子串,遍历子串中的所有字符,统计元音字母出现的个数。如果符合条件,我们就更新答案,但这样肯定会因为超时而无法通过所有测试用例。

方法: 前缀和 + 状态压缩

思路描述:官方题解的 前缀和+状态压缩 是真的没想到,这里稍微做个解释吧,

首先题目中要求子字符串中每个元音字母恰好出现偶数次,我们就可以使用 0 和 1 来标识每个字母的状态(偶数次或奇数次),我们不需要知道每个字母出现的完整次数,只需要知道这个次数的奇偶性

那么我们可以注意到奇数次 + 1 = 偶数次,偶数次 + 1 = 奇数次,所以我们可以使用 异或 来参与运算: 比如 aba

初始时 status = 00000,然后到 a 的时候 00000 ^ 00001 = 00001,1 说明 a 出现奇数次

然后到 b 的时候 00001 ^ 00010 = 00011,两个 1 说明 a、b 都出现奇数次

最后到 a 的时候 00011 ^ 00001 = 00010,说明只有 b 出现奇数次了。

以上也说明我们确实是可以使用状态码去标识每个元音字母出现次数的奇偶性。

那么我们怎么去统计最长子串的长度呢?

首先我们先盘盘哪些子串符合要求,因为现在每个下标对应的状态码其实也就只有 0 和 1

如果坐标 i 对应的状态码是 00011,坐标 j 对应的状态码是 00011,那么他们俩中间的元音字母数一定是偶数,如果某一位不相同,那么绝对不可能是偶数,因为偶数-奇数=奇数,奇数-偶数=奇数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值