この問題はManacher's Algorithmを使用して効率的に解決します。通常の方法では各クエリごとにO(N)時間かかりますが、事前計算によりO(1)時間でのクエリ処理を実現します。
偶数長・奇数長の回文を統一的に処理するため、文字間に特殊文字'#'を挿入します。
各位置を中心とした最長回文の半径を効率的に計算します。対称性を利用して無駄な計算を削減します。
| 位置 | 文字 | 半径 | 説明 |
|---|---|---|---|
| 0 | # | 0 | 境界 |
| 1 | m | 1 | 単一文字 |
| 7 | s | 1 | "s"単体 |
| 9 | # | 3 | "s#s" → 元文字列"ss" |
| 15 | # | 3 | "i#s#s#i" → 元文字列"issi" |
事前計算した半径配列を使用して、各クエリをO(1)時間で処理します。
radius[12] = 4 ≥ length = 4 → 回文!
| クエリ | 範囲 | 部分文字列 | 中心位置 | 必要半径 | 実際半径 | 結果 |
|---|---|---|---|---|---|---|
| 1 | [5,8] | "issi" | 12 | 4 | 4 | Yes |
| 2 | [6,10] | "ssipp" | 15 | 5 | 3 | No |
| 3 | [2,8] | "ississi" | 9 | 7 | 7 | Yes |
文字列とクエリを入力して、アルゴリズムの動作を確認してみましょう!