【競プロ典型90問】「034 - There are few types of elements(★4)」解法
Free-PhotosによるPixabayからの画像

問題

034 - There are few types of elements(★4)

ポイント

・〇〇を満たす区間 (連続する部分列) のうち、最小or最大の長さを求めよ
・〇〇を満たす区間 (連続する部分列) を数え上げよ

このような問題にはしゃくとり法が有効です。
※しゃくとり法については下記記事が参考になります。
【累積和、しゃくとり法】初級者でも解るアルゴリズム図解

実装したコードはこちらです。

コード

def main():
    import sys
    sys.setrecursionlimit(10 ** 9)
    input = sys.stdin.readline

    N, K = map(int, input().split())
    A = list(map(int, input().split()))

    cnt = dict()  # 各種類の要素の数
    kind = 0  # 種類の数
    ans = 1
    right = 0  # しゃくとり法の確認区間の右端インデックス

    # しゃくとり法
    for left in range(N):  # 確認区間の左端を1つずつ右にずらす
        while right < N and kind <= K:  # 右端がリスト内にありかつK種類以下
            if A[right] in cnt:  # 右端の種類を確認する
                cnt[A[right]] += 1
            else:
                cnt[A[right]] = 1
                kind += 1
            right += 1  # 確認区間の右端を1つ移動

        if kind <= K:  # right>=Nで抜けた場合(区間の右端が数列の最後までたどり着いた場合)
            ans = max(ans, right-left)
            break
        else:
            ans = max(ans, right - left - 1)  # kind>Kなので、右端は部分列に含めない

        cnt[A[left]] -= 1  # 確認区間の左端の種類の要素数を1減らす
        if cnt[A[left]] == 0:  # 左端の種類の要素数が0なら種類の数を1つ減らす
            kind -= 1
            del cnt[A[left]]

    print(ans)


if __name__ == '__main__':
    main()
おすすめの記事