Leetcode——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 次。

提示:

1 ≤ s . l e n g t h ≤ 5 × 1 0 5 1 \le s.length \le 5 \times 10^5 1s.length5×105
s 只包含小写英文字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts

题解

  1. 首先考虑最暴力的方法,那么就是枚举每个区间,统计区间内的元音的个数,从而得到区间最长的长度
  2. 那么每个区间需要计算,那么我们可用前缀和来优化, s u m [ i ] [ j ] sum[i][j] sum[i][j]表示前i个字符中的j个元音的个数。
  3. 因为要求的是区间内的元音是偶数,那么就要求,对于区间 [ l , r ] [l,r] [l,r] s u m [ r ] [ k ] − s u m [ l ] [ k ] sum[r][k] - sum[l][k] sum[r][k]sum[l][k]都是偶数,所以 s u m [ r ] [ k ] sum[r][k] sum[r][k] s u m [ l ] [ k ] sum[l][k] sum[l][k]都有相同的奇偶性。
  4. 如果我们用对2的模数表示奇偶性,那么只需要区间两端的对应的元音余数是相同的。因为余数为0或者1.。那么我们可以用二进制来表示。
  5. 因为共有5个元音,所以状态共有 2 5 − 1 2^5-1 251。所以可以用map来记录每个状态第一次出现的下标,记录一下最大的区间。
func max(a, b int) int {
    if a>b{
        return a 
    }
    return b
}
func findTheLongestSubstring(s string) int {
    status := 0
    mp := make(map[int]int,0)
    mp[0] = 0
    ans := 0
    for index,value := range s {
        if value == 'a' {
            status ^= (1<<0)
        } else if value == 'e' {
            status ^=(1<<1)
        } else if value == 'i' {
            status ^= (1<<2)
        } else if value == 'o' {
            status ^=(1<<3)
        } else if value == 'u' {
            status ^=(1<<4)
        }

        _,ok := mp[status]
        if ok {
            ans = max(ans,index+1-mp[status])
        } else {
            mp[status] = index+1
        }
    }
    return ans 
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页