貪欲で 3 つ組の最大から目標を作る

貪欲法問題 167

3 つの数の組の並びからいくつかを選び、位置ごとの最大を取って目標の組を作れるかを返す。目標を 1 か所でも越える組は使えないので捨て、残りの組で目標の 3 つの値がそろうかだけを見れば判定できます。

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

問題

ゲームの装備に、攻撃、守り、速さの 3 つの値があり、装備の一覧が 3 つの数の組の並び triplets で渡されます。いくつかの装備を選んで合成すると、合成した物の値は、選んだ装備の位置ごとの最大になります (攻撃は選んだ物の攻撃の最大、守りは守りの最大、速さは速さの最大)。目標の組 target とちょうど同じ値の物を作れるなら true、作れないなら false を返す関数を書いてください。

  • 選ぶ装備は 1 つ以上で、同じ装備を 2 回選ぶことはありません
  • 1 つだけ選んだときは、その装備の値がそのまま合成した物の値です
  • triplets の長さは 1 以上 100000 以下、値はどれも 1 以上 1000 以下です

入力と出力の例

例 1

[1, 6, 2] と [4, 3, 2] を選ぶと、位置ごとの最大は [4, 6, 2] です。[5, 6, 1] は攻撃が 5 で目標の 4 を越え、[2, 2, 7] は速さが 7 で目標の 2 を越えるので選べません。

triplets = [[1, 6, 2], [4, 3, 2], [5, 6, 1], [2, 2, 7]] target = [4, 6, 2]
true

例 2

[3, 5, 2] は守りが目標の 4 を越えるので選べません。残る [3, 1, 4] だけでは、守りが 1 のままです。

triplets = [[3, 1, 4], [3, 5, 2]] target = [3, 4, 4]
false

例 3

目標とちょうど同じ装備が 1 つあれば、それだけで作れます。

triplets = [[2, 9, 1], [7, 7, 7]] target = [7, 7, 7]
true

面接での聞かれ方

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

  • 「3 つ組の配列があります。いくつかを選んで要素ごとの最大を取ると、目標の 3 つ組になりますか」
  • 「選ぶ数に決まりはありますか」と聞くと、「いくつでも」と返ってくるのがふつうです
  • 書き終えたあとに「4 つ組、k 個組ならどうしますか」と、広げて聞かれることもあります

最大を取るのか合計を取るのかで、問題がまったく変わります。書く前に確かめておきます。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3答えに近い

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

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

main.py
def can_make_target(triplets: list[list[int]], target: list[int]) -> bool:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(can_make_target([[1, 6, 2], [4, 3, 2], [5, 6, 1], [2, 2, 7]], [4, 6, 2]))

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