A - 括弧の深さ / Depth of Parentheses Editorial by admin
Claude 4.5 Opus概要
正しく対応の取れた括弧列が与えられたとき、括弧の入れ子の最大の深さを求める問題です。
考察
重要な気づき
括弧の深さは、現在位置までに出現した ( の数から ) の数を引いた値で表現できます。
例えば ((())) を左から順に見ていくと:
- ( → 深さ 1
- (( → 深さ 2
- ((( → 深さ 3(ここが最大)
- ((() → 深さ 2
- (()) → 深さ 1
- ()) → 深さ 0
つまり、( が出てくるたびに深さが1増え、) が出てくるたびに深さが1減ります。
素朴なアプローチとの比較
この問題はスタックを使って解くこともできます。( をスタックに積み、) が来たらスタックから取り出す方法です。スタックの最大サイズが答えになります。
しかし、今回の問題では スタックに何を積んだかを記憶する必要がない(すべて ( なので)ため、スタックのサイズだけを整数変数で管理すれば十分です。これにより、空間計算量を \(O(N)\) から \(O(1)\) に削減できます。
アルゴリズム
- 変数
current_depth(現在の深さ)とmax_depth(最大の深さ)を \(0\) で初期化する - 文字列 \(S\) を先頭から1文字ずつ見ていく
(の場合:current_depthを \(1\) 増やし、max_depthを更新)の場合:current_depthを \(1\) 減らす
- 最終的な
max_depthが答え
具体例
入力が (()()) の場合:
| 位置 | 文字 | current_depth | max_depth |
|---|---|---|---|
| 0 | ( |
1 | 1 |
| 1 | ( |
2 | 2 |
| 2 | ) |
1 | 2 |
| 3 | ( |
2 | 2 |
| 4 | ) |
1 | 2 |
| 5 | ) |
0 | 2 |
答えは \(2\) となります。
計算量
- 時間計算量: \(O(|S|)\)
- 文字列を1回走査するだけ
- 空間計算量: \(O(1)\)
- 変数を2つ使うだけで、入力サイズに依存しない
実装のポイント
max_depthの更新は(を読んだ直後に行う必要があります。current_depthが増えた瞬間が、新しい深さに到達したタイミングだからです。正しく対応の取れた括弧列であることが保証されているため、
current_depthが負になるケースや、最終的に \(0\) にならないケースを考慮する必要はありません。ソースコード
S = input()
max_depth = 0
current_depth = 0
for c in S:
if c == '(':
current_depth += 1
max_depth = max(max_depth, current_depth)
else: # c == ')'
current_depth -= 1
print(max_depth)
この解説は claude4.5opus によって生成されました。
posted:
last update: