Pythonで「良い眺め」を持つ建物を見つけるプログラム
高さの異なる建物の高さを格納した配列が与えられているとします。建物は一列に並んでおり、ある建物が「良い眺め」を持つのは、それより高い別の建物によって視界が遮られない場合です。つまり、高さの配列が与えられたとき、他の高い建物に邪魔されずに眺めを楽しめる建物を見つけ出す必要があります。そして、その条件を満たす要素のインデックスを返します。
問題の例
例えば、入力が height = [5, 6, 8, 7] の場合、出力は [2, 3] となります。インデックス0と1の建物は、インデックス2にあるより高い建物に遮られています。一方、インデックス2と3の建物は遮られていません。これは、位置2にある高い建物が、位置3にある低い建物よりも後ろ(右側)に位置しているためです。
解決のためのアプローチ
この問題は、配列を右から左へ(末尾から先頭へ)走査することで効率的に解けます。手順は以下の通りです。
- 結果を格納する空のリスト
resと、それまでに見た最大の高さh(初期値0)を用意します。 - 配列の末尾から先頭に向かって各建物を調べます。
- 現在の建物の高さ
heights[i]がhより大きければ、その建物は遮られないため、インデックスiをresに追加し、hを更新します。 - 最後に
resを反転して返します。これにより、インデックスが左から右の自然な順序になります。
このアルゴリズムの時間計算量は O(n)、空間計算量も O(n) であり、非常に効率的です。
実装例
以下のPythonコードを見て、理解を深めましょう。
def solve(heights):
res, h = [], 0
for i in range(len(heights) - 1, -1, -1):
if heights[i] > h:
res.append(i)
h = heights[i]
return res[::-1]
print(solve([5, 6, 8, 7]))
入力
[5, 6, 8, 7]
出力
[2, 3]
-
Pythonで全都市の市民が市場にアクセスできるようにする最小コストを求めるプログラム
問題の概要n個の都市と、それらを結ぶm本の道路候補があるとします。市民が日用品を購入するには市場へのアクセスが必要ですが、現時点ではどの都市にも市場は存在せず、都市間の道路もまだ建設されていません。2つの都市間に双方向の道路を建設できるのは、次の条件を満たす場合のみです。片方の都市に市場が存在すること市場のある地点から道路を経由してその都市へ到達できること道路を1本建設するコストは x、市場を1つ建設するコストは y として与えられます。求めたいのは、すべての都市の市民が市場にアクセスできるようにするための最小コストです。配列 cities には、どの都市同士を道路で接続できるかという情報が含
-
Pythonでグラフがすべての人にとって移動可能かどうかを確認するプログラム
n個の頂点(0からn-1までの番号が付けられたもの)から構成される無向グラフが与えられます。各辺には重みが設定されており、重みは「1」「2」「3」の3種類があります。このグラフを移動できるのはJackとCaseyの2人で、Jackは重み1の辺のみ、Caseyは重み2の辺のみを移動でき、重み3の辺は両方が移動できます。 ここで、JackとCaseyの両方がグラフ内のすべての頂点に到達できるようにするために、不要な辺を削除することを考えます。このとき削除が必要な辺の本数を求め、どのようにしても移動可能な状態にできない場合は-1を返します。 例えば、入力が次のような場合を考えてみましょう。 n =