0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LeetCodeWeekly238C: 1839. Longest Substring Of All Vowels in Order 区間操作 一定の文字出現する最大の単調増加文字列

Last updated at Posted at 2021-04-27

題意(オリジナル)

  • 英語小文字の集合である文字列$s$が与えられる.
  • 良い文字列を以下のように定義する.ソートされた$x$文字の連続した文字列であり、この中に$a,i,u,e,o$の5文字が1回以上出現していなければならない.
  • この文字列の長さの最大長を求めよ

こう考えた

簡単のため、問題文を以下のように言い換える.

  • $|s|$の配列$a$が与えられ、各要素 $a_i$は $0 \leq a_i \leq 25$である
  • よい区間とは以下の通りである.連続した区間の要素が全てソートされており(つまり、単調増加)、この中に$0, 8, 20, 4, 15$が1度以上含まれている

ここで、連続した区間とは、ある任意の $ 0 \leq l \leq r < |s| $と言い換えられる.さて、ここで単調増加である条件を考えると、ある$l$を固定した際、$r$を右に伸ばしていき、伸ばせるところまで伸ばし、その中に、$0, 8, 20, 4, 15$が含まれているならばそれは最長の長さの候補として扱える.

このため、以下のように判定をする.

  • l = 0からスタートし、単調増加で有る限り、rをインクリメントする
  • 単調増加でなくなった場合、今の区間に必要な文字が含まれているかを判定する.
  • Yesの場合、その文字長を候補とする.Noの場合、捨てる

実装

特に留意点はなし.工夫は以下程度.

  • 先に$s$は数値のリストにしておく方が良い
class Solution:
    def longestBeautifulSubstring(self, word: str) -> int:
        judge = lambda : cnt[0]!=0 and cnt[8]!=0 and cnt[20]!=0 and cnt[4]!=0 and cnt[14]!=0
        chr2int = lambda x: ord(x) - ord("a")
        s,l,r = word,0,0
        s = list(map(chr2int, s))
        cnt = [0] * 26
        res = 0
        p = -1
        while r < len(s):
            cnt[s[r]] += 1
            # 足した文字が条件を達成しているか?
            if s[r] < p:
                l = r
                r += 1
                p = s[r]
                continue
            p = s[r]
            if judge(): # 文字が足りている
                res = max(res, (r-l) + 1)
            r += 1
        return res

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?