Python
 Computer >> コンピューター >  >> プログラミング >> Python

【Python】隣り合わない条件で全員が座席に着席できるかを判定するアルゴリズム

n 人の人が座席を探している状況を考えます。座席の状態はビットのリストで表され、1 はすでに使用されている座席、0 は空いている座席を意味します。ただし、隣り合う座席に同時に着席することはできません。このとき、n 人全員が座席に見つけられるかどうかを判定するのが本記事のテーマです。

例えば、入力が n = 2、seats = [1, 0, 0, 0, 1, 0, 0] の場合、出力は True になります。インデックス 2 と 6 の空き座席に、互いに隣接しない形で着席できるからです。

解法のアプローチ

この問題は、連続する空き座席(0 の並び)ごとに、条件を満たして着席できる人数を数えることで解けます。長さ gap の連続した空き区間には、隣接しないように最大で (gap - 1) ÷ 2 の切り捨て値の人間が座れます。

具体的な手順は以下の通りです。

  • seats の先頭に 0 を挿入し、末尾に [0, 1] を追加します。これにより、リストの両端にある空き区間も確実に処理できるようになります。
  • 累積カウンタ res := 0、現在の空き区間の長さ gap := 0 で初期化します。
  • seats の各要素 i について、次の処理を行います。
    • i が 0 の場合:gap を 1 増やします。
    • それ以外の場合(i が 1 のとき)で gap > 0 の場合:res に (gap - 1) // 2 を加算し、gap を 0 にリセットします。
  • 最後に、res >= n であれば true を返し、そうでなければ false を返します。

実装例

理解を深めるために、以下の Python 実装を見てみましょう。

def solve(n, seats):
    seats = [0] + seats + [0, 1]
    res = 0
    gap = 0
    for i in seats:
        if i == 0:
            gap += 1
        elif gap > 0:
            res += (gap - 1) // 2
            gap = 0
    return res >= n

n = 2
seats = [1, 0, 0, 0, 1, 0, 0]
print(solve(n, seats))

入力

2, [1, 0, 0, 0, 1, 0, 0]

出力

True

コードのポイント

  • 番兵(パディング)の活用: 先頭の 0 は「最初の座席が空いているケース」でも正しく数えられることを保証し、末尾の [0, 1] はループ終了後に残った空き区間を確実に集計するために追加しています。
  • 効率性: 座席リストを一度だけ走査すればよいため、時間計算量は座席数 m に対して O(m) と非常に効率的です。
  1. Pythonで左右の部分木の入れ替えにより2つの二分木を一致させられるか判定する方法

    問題の概要 2つの二分木が与えられたとき、任意のノードについて左部分木と右部分木を何度でも入れ替えてよいと仮定します。この操作を繰り返すことで、1つ目の木を2つ目の木とまったく同じ形に変換できるかどうかを判定するのが、この記事で扱う問題です。 例えば、次のような2つの木が入力として与えられた場合、左右の入れ替えによって一致させられるため、出力は True になります。 解決のアプローチ この問題は、幅優先探索(BFS)の考え方を使い、木をレベル(深さ)ごとに処理しながらノードの値を比較することで解けます。左右の入れ替えによって同じレベル内の値の並び順は反転し得るため、「順方向」または「逆方

  2. Pythonで与えられたグラフが2部グラフかどうかを判定するプログラム

    2部グラフとは無向グラフが与えられたとき、そのグラフが2部グラフ(バイパータイトグラフ)であるかどうかを判定する方法を解説します。2部グラフとは、グラフのすべての頂点を2つの集合 A と B に分割でき、グラフ内のすべての辺 {u, v} が必ず一方の端点 u が集合 A、もう一方の端点 v が集合 B に属するようなグラフのことです。つまり、同じ集合内の頂点同士を結ぶ辺(A-A や B-B)が一切存在しないグラフです。例として、次のようなグラフを考えてみましょう。この場合、頂点 [0, 4] を集合 A に、[1, 2, 3] を集合 B に分類できます。すべての辺は A から B、または