貪欲で札を連続する数の組に分ける

貪欲法問題 166

数の書かれた札の束を、決まった枚数の連続する数の組に全部分けられるかを返す。残っている最も小さい札は必ず組の先頭になるので、小さい順に組を作っていくだけで判定できます。

海外で定番の問題リスト 4 本には入っていません

問題

カードゲームで、数の書かれた札の並び cards と、組の枚数 size が渡されます。札を全部使い、どの組も size 枚の連続する数 (たとえば 4、5、6) でできるように分けられるなら true、分けられないなら false を返す関数を書いてください。

  • 同じ数の札が何枚あることもあります。1 つの組の中に同じ数は入りません
  • cards の枚数が size で割り切れなければ、分けられないので false です
  • size が 1 なら、どの札も 1 枚で組になるので true です
  • cards の長さは 1 以上 10000 以下、値はどれも 0 以上 1000000000 以下、size は 1 以上 cards の長さ以下です

入力と出力の例

例 1

[3, 4, 5]、[4, 5, 6]、[10, 11, 12] の 3 組に分けられます。

cards = [5, 3, 4, 10, 11, 12, 4, 6, 5] size = 3
true

例 2

2 を含む組は [2, 3] しかなく、残りの 4, 4, 5, 6 では 4 が 2 枚とも 5 を要るのに、5 は 1 枚しかありません。

cards = [2, 3, 4, 4, 5, 6] size = 2
false

例 3

4 枚は 3 で割り切れないので、数を見るまでもなく分けられません。

cards = [8, 9, 10, 11] size = 3
false

面接での聞かれ方

面接では、トランプやカードゲームの話として出されることが多いです。

  • 「手札を、同じ枚数の連番の組に分けられますか」
  • 「同じ数の札は何枚ありますか」と聞くと、「何枚でもあります」と返ってくるのがふつうです
  • 書き終えたあとに「値の幅が小さいと分かっているなら速くできますか」と、続きを聞かれることもあります

同じ数の札が複数あるか、組の中で同じ数を使えるかを、書く前に確かめておきます。

ヒント

まだ開いていません

付箋は 3 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3答えに近い

アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。

配列と文字列の問題は、全部の組を調べると手間が大きくなる所を、窓や左右の添字で減らす形が多いです。

main.py
def can_split_straights(cards: list[int], size: int) -> bool:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(can_split_straights([5, 3, 4, 10, 11, 12, 4, 6, 5], 3))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します