貪欲で最後のマスに着けるかを判定する

貪欲法問題 163

すごろくのマスごとに進める歩数の上限が決まっているとき、最初のマスから最後のマスに着けるかを返す。「いままでに届く最も遠いマス」を 1 つ持ち歩き、前から 1 回なめるだけで判定できます。

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

問題

すごろくのマスが一列に並び、マス i からは 1 歩以上 steps[i] 歩以下の好きな歩数だけ前へ進めます (steps[i] が 0 のマスからは進めません)。最初のマス (番号 0) から始めて、最後のマス (番号 len(steps) - 1) に着けるなら true、着けないなら false を返す関数を書いてください。

  • 後ろへ戻ることはできません
  • 最後のマスを越える歩数を選ぶことはできませんが、上限が大きいマスから少ない歩数を選ぶことはできます
  • マスが 1 つだけなら、最初から最後のマスにいるので true です
  • steps の長さは 1 以上 100000 以下、値はどれも 0 以上 100000 以下です

入力と出力の例

例 1

マス 0 から 1 へ進み、マス 1 から 3 歩でマス 4 へ、マス 4 から 2 歩で最後のマス 6 に着きます。途中の 0 のマスは飛び越せます。

steps = [1, 3, 0, 0, 2, 0, 1]
true

例 2

マス 0、1、2 のどこからも、マス 3 より先へは届きません。マス 3 の値は 0 なので、そこで止まります。

steps = [2, 1, 0, 0, 5]
false

例 3

マスが 1 つだけなので、最初から着いています。

steps = [0]
true

面接での聞かれ方

面接では、短い一文で渡されることが多いです。

  • 「各要素がそこから跳べる最大の距離を表す配列があります。最後まで行けますか」
  • 最初に動的計画法で書き、「もっと速くできますか」と聞かれて貪欲に直す流れもあります
  • 解けたら「最少で何回跳べば着きますか」と、次の問題へ広げられることもあります

値がちょうどの歩数なのか、上限なのかで問題が変わります。書く前に確かめておきます。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3答えに近い

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

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

main.py
def can_reach_end(steps: list[int]) -> bool:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(can_reach_end([1, 3, 0, 0, 2, 0, 1]))

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