Pythonで括弧のバランスが取れているかどうかをチェックするプログラム
文字列 s が、開き括弧「(」と閉じ括弧「)」のみで構成されているとします。ここでは、括弧の対応(バランス)が正しく取れているかどうかを判定するプログラムを作成します。
たとえば、入力が s = "(()())(())" の場合、すべての括弧が正しく入れ子になっているため、出力は True になります。一方、「)(」のように閉じ括弧が先に現れたり、開き括弧が余ったりする場合は False となります。
解き方のアプローチ
この問題は、整数型のカウンターを1つ用意するだけで効率的に解けます。手順は次のとおりです。
- カウンター
num_openを 0 で初期化する。 - 文字列
s内の各文字cについて、以下を繰り返す。cが「(」の場合:num_openを +1 する。cが「)」の場合:num_openを −1 し、結果が負になったら、対応する開き括弧がない閉じ括弧が現れたことを意味するため、直ちにFalseを返す。
- すべての文字を処理した後、
num_openが 0 であればTrue、そうでなければFalseを返す。
つまり、開き括弧を「+1」、閉じ括弧を「−1」としてカウントし、「途中でマイナスにならないこと」と「最後にちょうど 0 に戻ること」の2つを確認するのがポイントです。
実装例
class Solution:
def solve(self, s):
num_open = 0
for c in s:
if c == '(':
num_open += 1
elif c == ')':
num_open -= 1
if num_open < 0:
return False
return num_open == 0
ob = Solution()
print(ob.solve("(()())(())"))
入力
"(()())(())"
出力
True
よくある注意点
- 最後にカウンターが 0 かどうかの確認を忘れないこと。「((()」のように開き括弧が余っているケースを見逃してしまいます。
- 閉じ括弧の処理中にカウンターが 0 未満になった時点で、それ以降を調べる必要はありません。早期リターンすることで無駄な処理を省けます。
計算量
文字列を一度だけ走査するため、時間計算量は O(n)。使用するのはカウンター1つだけなので、空間計算量は O(1) です。非常に長い文字列でも高速に判定できる、シンプルかつ実用的なアルゴリズムです。
-
Pythonで2つの二分木の葉の並び(シーケンス)が同じかどうかを確認する方法
はじめに2つの二分木が与えられたとき、それぞれの木を左から右へたどったときの葉ノードの並び(シーケンス)が一致しているかどうかを判定する問題を考えてみましょう。例えば、次のような2つの木が入力として与えられた場合を想定します。この場合、どちらの木も葉の並びは [2, 6] となるため、出力は True になります。解決のアプローチこの問題を解くためには、以下の手順に従います。結果を格納するための新しいリスト c を用意します。inorder() 関数を定義します。この関数はルートノードとリスト c を引数に取ります。c が null の場合は、新しい空のリストを作成します。ルートノードが nu
-
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、または