以下では、TypeScript の解法コードに基づき、各処理の目的・流れ・具体例・図解 を使って、できる限りわかりやすく解説します。
対応の取れているカッコ列:
- 例:
(())()は以下のようにすべての括弧が正しく閉じている。
| 位置(1-indexed) | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 文字 | ( | ( | ) | ) | ( | ) |
対応関係は:
2と31と45と6
1. 入力文字列 S を受け取る
2. 左括弧 '(' をスタックに積む
3. 右括弧 ')' に対応する '(' をスタックから取り出す
4. 取り出したペアを結果に保存
5. 結果を `max(l, r)` 昇順にソート
6. 出力if (S[i] === '(') {
stack.push(i + 1);
} else {
const left = stack.pop();
if (left !== undefined) {
pairs.push([left, i + 1]);
}
}| 処理位置 | 入力 | スタック | 操作 | 結果ペア |
|---|---|---|---|---|
| i = 0 | ( | [1] | push(1) | [] |
| i = 1 | ( | [1, 2] | push(2) | [] |
| i = 2 | ) | [1] | pop → [2,3] | [[2,3]] |
| i = 3 | ) | [] | pop → [1,4] | [[2,3],[1,4]] |
| i = 4 | ( | [5] | push(5) | [[2,3],[1,4]] |
| i = 5 | ) | [] | pop → [5,6] | [[2,3],[1,4],[5,6]] |
pairs.sort((a, b) => Math.max(a[0], a[1]) - Math.max(b[0], b[1]));出力条件:
- 対応ペア
[l, r]は、max(l, r)の 昇順 に並べる。
[[2, 3], [1, 4], [5, 6]]
| ペア | max(l, r) |
|---|---|
| [2, 3] | 3 |
| [1, 4] | 4 |
| [5, 6] | 6 |
→ すでに昇順なので、このままでOK。
const output: string = result.map(([l, r]) => `${l} ${r}`).join('\n');
console.log(output);各ペア [l, r] を l r の形式で 1 行ずつ出力:
2 3
1 4
5 6
Input: "(())()"
↑
スタックを使って対応を記録
┌────────┐
S = ( ( ) ) ( )
↑ ↑ ↑ ↑ ↑ ↑
pos 1 2 3 4 5 6
対応関係(括弧の組):
(2,3)
(1,4)
(5,6)
→ max(l,r) で昇順ソートして出力
Output:
2 3
1 4
5 6
| 項目 | 計算量 | 理由 |
|---|---|---|
| 時間計算量 | O(N log N) | 探索 O(N)、ソート O(N log N) |
| 空間計算量 | O(N) | スタック + 結果配列 |
この処理は最大 200,000 長の文字列にも高速に対応でき、制約内で動作するよう設計されています。
カッコ列の対応問題について、HTMLを使って詳細な図解と解析を作成します。この詳細な解析では、カッコ列対応問題の各処理について以下の観点から図を使って説明しています:
- 入力データの可視化: 文字列の各位置を明確に表示
- アルゴリズムの処理フロー: 4つのステップに分けた処理の流れ
- ステップバイステップ実行トレース: 各文字の処理過程を詳細に追跡
- スタック操作の可視化: 各段階でのスタックの状態変化
- ソート処理の詳細: なぜその順序になるかの数学的根拠
- 計算量分析: 時間とメモリの使用量の理論的解析
- アルゴリズムの正当性: なぜこの方法で正しい答えが得られるかの説明
- スタックの動作: LIFO性質により内側のカッコから順に処理
- ソート条件:
max(li, ri) < max(li+1, ri+1)の意味と必要性 - メモリ効率: O(n)の空間計算量で効率的に処理
- 時間効率: O(n log n)でソートが律速段階
この可視化により、アルゴリズムの各段階での状態変化と、なぜそのような処理が必要なのかが直感的に理解できるようになっています。
| 提出日時 | 問題 | ユーザ | 言語 | 得点 | コード長 | AI tool | 実行時間 | メモリ | |
|---|---|---|---|---|---|---|---|---|---|
| 2025-08-06 13:46:29 | B51 - Bracket | myoshizumi | Go (go 1.20.6) | 1000 | 1441 Byte | ChatGPT | 122 ms | 5676 KiB | 詳細 |
| 2025-08-06 13:44:10 | B51 - Bracket | myoshizumi | PHP (php 8.2.8) | 1000 | 1250 Byte | ChatGPT | 263 ms | 50884 KiB | 詳細 |
| 2025-08-06 13:39:50 | B51 - Bracket | myoshizumi | Python (CPython 3.11.4) | 1000 | 7254 Byte | Claude Sonnet 4 | 599 ms | 82852 KiB | 詳細 |
| 2025-08-06 13:37:49 | B51 - Bracket | myoshizumi | Python (CPython 3.11.4) | 1000 | 1101 Byte | ChatGPT | 78 ms | 33536 KiB | 詳細 |
| 2025-08-06 13:23:29 | B51 - Bracket | myoshizumi | TypeScript 5.1 (Node.js 18.16.1) | 1000 | 2929 Byte | Claude Sonnet 4 | 103 ms | 85052 KiB | 詳細 |
| 2025-08-06 13:22:20 | B51 - Bracket | myoshizumi | TypeScript 5.1 (Node.js 18.16.1) | 1000 | 1219 Byte | ChatGPT | 106 ms | 84900 KiB | 詳細 |
| 2025-08-06 13:17:30 | B51 - Bracket | myoshizumi | JavaScript (Node.js 18.16.1) | 1000 | 1057 Byte | ChatGPT | 98 ms | 84960 KiB | 詳細 |