zoukankan      html  css  js  c++  java
  • 【Leetcode刷题】每个元音包含偶数次的最长子字符串

    https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/

    这题真的太难了,看答案都想了两个小时,我建议调整难度为困难不过分吧?orz

    class Solution:
        def findTheLongestSubstring(self, s: str) -> int:
            # 前缀和+状态压缩
            # 记录s[:i]中五个元音的奇偶数量pattern,如果s[:j]的pattern与s[:i]相同,则s[i+1:j]的元音数量都是偶数
            # 五个元音,每个都有奇偶两种状态,因此pattern的数量为2^5=32
            # 记录每个pattern最早出现的位置(因为需要求最长子串)
            # 如果pattern没有出现过,则初始化为None
            memo = [None for _ in range(32)]
            # 还没开始遍历s时,所有元音都没有出现,因此是[00000]=0,并且此时索引为-1,即第一个字符之前的位置
            memo[0] = -1
            # 遍历过程中元音的pattern
            pattern = 0
            # 符合要求子字符串的最大长度
            max_len = 0
            for i in range(len(s)):
                # 做位运算求出当前pattern
                if s[i] == 'a':
                    pattern ^= (1 << 0)
                elif s[i] == 'e':
                    pattern ^= (1 << 1)
                elif s[i] == 'i':
                    pattern ^= (1 << 2)
                elif s[i] == 'o':
                    pattern ^= (1 << 3)
                elif s[i] == 'u':
                    pattern ^= (1 << 4)
                if memo[pattern] is not None:
                    # 以s[i]结尾的符合要求的最长子字符串
                    # 为什么是这样,一步步写出"leetcodeo"遍历过程pattern和max_len的变化就懂了
                    cur_len = i - memo[pattern]
                    max_len = max(cur_len, max_len)
                else:
                    # 为什么这里只更新memo不求max_len呢?
                    # 因为当memo[pattern] is None,说明这个pattern以前没有出现过
                    # 说明s[i]必然是一个元音,因为pattern被更新了
                    # 并且不存在s[j:i]符合条件,s[i]这个子字符串也不符合条件,因为当前元音出现了一次
                    # 因此这种情况下cur_len=0,不需要更新max_len
                    memo[pattern] = i
            return max_len
    

    时间复杂度:O(n)

    空间复杂度:O(len(memo))

  • 相关阅读:
    Maven版本管理
    ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口
    java常用集合框架关系
    重写equals和hashCode
    项目的继承和聚合详解
    Installation Manager1.8安装
    关于java按位操作运算
    正数负数的二进制表示
    springboot问题排解
    int和Integer有什么区别
  • 原文地址:https://www.cnblogs.com/luozx207/p/12924822.html
Copyright © 2011-2022 走看看