この記事について: 科目B のアルゴリズム5パターンを1ページで完全網羅する練習問題集です。各問題は「疑似言語コード→選択肢→正答→ハンドトレース表→解法のポイント」の形式で、なぜその答えになるかを丁寧に解説します。IPAの公式疑似言語記法に準拠しています。
VolatileBox - 出題構成・配点(変動値・要確認)
科目Bの出題構成(アルゴリズム16問・セキュリティ4問・合計20問)はIPA公式の最新試験案内で確認してください。確認日:2026-06-08。出典:IPA 基本情報技術者試験 出題範囲・シラバス。
疑似言語の基本記法(問題を解く前に必ず確認)
| 記法 | 意味 | 例 |
|---|---|---|
| `整数型: 変数名` | 変数の宣言 | `整数型: x` |
| `変数名 ← 値` | 代入 | `x ← 5` |
| `変数名 = 値` | 等値比較(条件式内) | `x = 5` ならば |
| `もし (条件) ならば ... を実行する` | 条件分岐 | — |
| `i を 1 から N まで 1 ずつ増やしながら繰り返す` | カウンタループ | — |
| `(条件) の間,繰り返す` | 条件ループ | — |
| `a[i]` | 配列の i 番目の要素 | — |
| `関数名(引数)` | 関数呼び出し | `max(a, b)` |
参照: IPA 基本情報技術者試験 擬似言語の仕様
---
パターン1:線形探索・集計系(4問)
最頻出パターン。配列を先頭から末尾まで1要素ずつ走査し、合計・最大値・出現回数などを計算します。変数表に「i(インデックス)」と「集計変数」の2列を作るだけで解けます。
---
問題1-1:配列の合計値
疑似言語コード
```
整数型配列: a ← [3, 7, 2, 8, 5]
整数型: i, goukei
goukei ← 0
i を 1 から 5 まで 1 ずつ増やしながら繰り返す
goukei ← goukei + a[i]
を繰り返す
```
次のコードを実行したとき、goukei の値はいくつになるか。
選択肢:
- ア 20
- イ 23
- ウ 25
- エ 28
正答: ウ(25)
ハンドトレース表:
| i | a[i] | goukei |
|---|---|---|
| 初期 | — | 0 |
| 1 | 3 | 3 |
| 2 | 7 | 10 |
| 3 | 2 | 12 |
| 4 | 8 | 20 |
| 5 | 5 | 25 |
解法のポイント: goukei を0で初期化し、ループで a[i] を加算し続けるだけです。配列が1始まりか0始まりかに注意(この問題は1始まり)。
---
問題1-2:最大値の検出
疑似言語コード
```
整数型配列: a ← [4, 9, 2, 6, 1, 8]
整数型: i, maxVal
maxVal ← a[1]
i を 2 から 6 まで 1 ずつ増やしながら繰り返す
もし (a[i] > maxVal) ならば
maxVal ← a[i]
を実行する
を繰り返す
```
次のコードを実行したとき、maxVal の値はいくつになるか。
選択肢:
- ア 6
- イ 8
- ウ 9
- エ 10
正答: ウ(9)
ハンドトレース表:
| i | a[i] | a[i] > maxVal? | maxVal |
|---|---|---|---|
| 初期 | — | — | 4(a[1]) |
| 2 | 9 | 9 > 4 → TRUE | 9 |
| 3 | 2 | 2 > 9 → FALSE | 9 |
| 4 | 6 | 6 > 9 → FALSE | 9 |
| 5 | 1 | 1 > 9 → FALSE | 9 |
| 6 | 8 | 8 > 9 → FALSE | 9 |
解法のポイント: 最大値検出は「最初の要素でmaxValを初期化→ループはi=2から」というパターンが固定。ループをi=1から始めると自分自身との比較が1回入るが結果は同じ。初期値の取り方を間違えないこと。
---
問題1-3:条件を満たす要素の個数
疑似言語コード
```
整数型配列: scores ← [72, 58, 85, 91, 63, 78, 45, 88]
整数型: i, count
count ← 0
i を 1 から 8 まで 1 ずつ増やしながら繰り返す
もし (scores[i] >= 70) ならば
count ← count + 1
を実行する
を繰り返す
```
次のコードを実行したとき、count の値はいくつになるか。
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: ウ(5)
ハンドトレース表:
| i | scores[i] | >= 70? | count |
|---|---|---|---|
| 初期 | — | — | 0 |
| 1 | 72 | TRUE | 1 |
| 2 | 58 | FALSE | 1 |
| 3 | 85 | TRUE | 2 |
| 4 | 91 | TRUE | 3 |
| 5 | 63 | FALSE | 3 |
| 6 | 78 | TRUE | 4 |
| 7 | 45 | FALSE | 4 |
| 8 | 88 | TRUE | 5 |
解法のポイント: 70以上(≥70)を満たす要素は72・85・91・78・88の5個。「>70(70より大きい)」と「>=70(70以上)」の区別が試験で問われるため、境界値(= が含まれるかどうか)を必ず確認してください。
---
問題1-4:平均値と閾値比較
疑似言語コード
```
整数型配列: a ← [10, 20, 30, 40, 50]
整数型: i, goukei, heikin
goukei ← 0
i を 1 から 5 まで 1 ずつ増やしながら繰り返す
goukei ← goukei + a[i]
を繰り返す
heikin ← goukei / 5
```
次のコードを実行したとき、heikin の値はいくつになるか。ただし整数の割り算は小数点以下を切り捨てる。
選択肢:
- ア 28
- イ 30
- ウ 32
- エ 35
正答: イ(30)
ハンドトレース表:
| ステップ | 計算 | 結果 |
|---|---|---|
| goukei初期化 | 0 | 0 |
| +a[1] | 0+10 | 10 |
| +a[2] | 10+20 | 30 |
| +a[3] | 30+30 | 60 |
| +a[4] | 60+40 | 100 |
| +a[5] | 100+50 | 150 |
| heikin | 150/5 | 30 |
解法のポイント: 合計を求めてからN(要素数)で割る2段階の計算。整数除算の切り捨てに注意(この問題では割り切れるため影響なし)。配列の要素数と除数を合わせることが重要です。
---
パターン2:二分探索(4問)
ソート済み配列を対象に、中央値との比較で探索範囲を半分に絞る高速探索アルゴリズム。lo(下限)・hi(上限)・mid(中央) の3変数の変化を縦に追うことが解法の核心です。
---
問題2-1:基本的な二分探索
疑似言語コード
```
整数型配列: a ← [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
整数型: lo, hi, mid, target
target ← 23
lo ← 1
hi ← 10
(lo <= hi) の間,繰り返す
mid ← (lo + hi) / 2 / 整数除算(切り捨て) /
もし (a[mid] = target) ならば
lo ← hi + 1 / 探索終了(ループを抜ける) /
そうでなく もし (a[mid] < target) ならば
lo ← mid + 1
そうでなければ
hi ← mid - 1
を実行する
を繰り返す
```
ループが終了したとき、最後に mid が指していたインデックスはいくつか。
選択肢:
- ア 4
- イ 5
- ウ 6
- エ 7
正答: ウ(6)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | 比較結果 |
|---|---|---|---|---|---|
| 1 | 1 | 10 | 5 | 16 | 16 < 23 → lo←6 |
| 2 | 6 | 10 | 8 | 56 | 56 > 23 → hi←7 |
| 3 | 6 | 7 | 6 | 23 | 23 = 23 → 探索終了 |
解法のポイント: target=23はインデックス6の要素(1始まり)。3回の反復で発見。mid の計算は (lo+hi)/2 の整数部のみ取ることに注意。ループ終了条件「lo > hi」または「発見時の強制終了」の両方を把握してください。
---
問題2-2:探索失敗時の動作
疑似言語コード(問題2-1と同じ配列・同じロジック)
```
target ← 15
lo ← 1
hi ← 10
(lo <= hi) の間,繰り返す
mid ← (lo + hi) / 2
もし (a[mid] = target) ならば
lo ← hi + 1
そうでなく もし (a[mid] < target) ならば
lo ← mid + 1
そうでなければ
hi ← mid - 1
を実行する
を繰り返す
```
target=15 は配列に存在しない。ループが終了したとき、lo と hi の値の組み合わせとして正しいものはどれか。
選択肢:
- ア lo=4, hi=4
- イ lo=5, hi=4
- ウ lo=4, hi=3
- エ lo=5, hi=3
正答: イ(lo=5, hi=4)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | 比較(target=15) |
|---|---|---|---|---|---|
| 1 | 1 | 10 | 5 | 16 | 16 > 15 → hi←4 |
| 2 | 1 | 4 | 2 | 5 | 5 < 15 → lo←3 |
| 3 | 3 | 4 | 3 | 8 | 8 < 15 → lo←4 |
| 4 | 4 | 4 | 4 | 12 | 12 < 15 → lo←5 |
| 5 | 5 | 4 | — | lo > hi → ループ終了 |
解法のポイント: 探索失敗時は lo > hi になってループを抜けます。最後の反復でloが5になり、hiが4のままでlo > hiが成立してループ終了。この「失敗時の状態」を問う問題は本番でも頻出です。
---
問題2-3:二分探索の繰り返し回数
配列要素数Nに対して二分探索の最大繰り返し回数を求める問題です(コードなし・論理問題)。
要素数 N = 1,000 のソート済み配列に対して二分探索を行う場合、最大で何回の比較(mid の計算・比較)が必要か。ただし log₂(1000) ≈ 9.96 とする。
選択肢:
- ア 10回
- イ 11回
- ウ 1000回
- エ 500回
正答: ア(10回)
解説: 二分探索の最大比較回数は ⌈log₂(N)⌉ です。N=1000 の場合、log₂(1000) ≈ 9.96 であり、切り上げて 10回 となります。線形探索が最大N=1000回かかるのに対し、二分探索は最大10回と劇的に少ない。この「計算量の違い(O(N) vs O(log N))」は科目Aでも出題される重要概念です。
解法のポイント: 1回の比較で探索範囲が「半分」になる → N回比較すると範囲が 1/2^N になる → 範囲が1以下(= 探索終了)になるのは log₂(N) 回。暗算できるように整理:10回で2^10=1024 > 1000なので10回で十分。
---
問題2-4:二分探索の変形(下限探索)
疑似言語コード
```
整数型配列: a ← [3, 3, 5, 7, 7, 7, 9, 11]
整数型: lo, hi, mid, target, ans
target ← 7
lo ← 1
hi ← 8
ans ← -1
(lo <= hi) の間,繰り返す
mid ← (lo + hi) / 2
もし (a[mid] >= target) ならば
ans ← mid
hi ← mid - 1
そうでなければ
lo ← mid + 1
を実行する
を繰り返す
```
ループが終了したとき、ans の値はいくつか(target が最初に現れるインデックスを求めている)。
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: イ(4)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | >= 7? | ans | 操作 |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 8 | 4 | 7 | YES | 4 | hi←3 |
| 2 | 1 | 3 | 2 | 3 | NO | 4 | lo←3 |
| 3 | 3 | 3 | 3 | 5 | NO | 4 | lo←4 |
| 終了 | 4 | 3 | — | lo > hi | — | 4 | — |
解法のポイント: 通常の二分探索を変形して「target 以上の最小インデックス(lower_bound)」を求めるパターンです。a[mid] >= target のときに ans を記録し、さらに左を探索する(hi←mid-1)ことで、最も左の出現位置を確定します。この変形パターンは本番で出題されることがあり、通常の二分探索と混同しないよう注意が必要です。
---
パターン3:ソートアルゴリズム(4問)
配列を昇順/降順に並び替えるアルゴリズム。バブルソート・選択ソート・挿入ソートの3種類が頻出。各パスごとの配列状態を縦に並べて書くことがトレースの基本です。
---
問題3-1:バブルソートのパス後状態
配列 [5, 3, 8, 1, 4] をバブルソート(隣接要素の比較・交換)で昇順に並び替えるとき、1パス目が終了した直後の配列の状態として正しいものはどれか。
ただしバブルソートの1パスとは「先頭から末尾に向かって隣接要素を比較し、前の要素が後の要素より大きければ交換する」操作を1回実施することとする。
選択肢:
- ア [1, 3, 5, 4, 8]
- イ [3, 5, 1, 4, 8]
- ウ [3, 1, 5, 4, 8]
- エ [1, 3, 4, 5, 8]
正答: イ([3, 5, 1, 4, 8])
ハンドトレース(1パス目):
| 比較位置 | 比較 | 交換? | 配列の状態 |
|---|---|---|---|
| 初期 | — | — | [5, 3, 8, 1, 4] |
| a[1]とa[2] | 5 > 3 | YES | [3, 5, 8, 1, 4] |
| a[2]とa[3] | 5 < 8 | NO | [3, 5, 8, 1, 4] |
| a[3]とa[4] | 8 > 1 | YES | [3, 5, 1, 8, 4] |
| a[4]とa[5] | 8 > 4 | YES | [3, 5, 1, 4, 8] → [3, 5, 1, 4, 8] |
解法のポイント: バブルソート1パス後は「最大値が末尾に確定」します(8が末尾へ)。先頭から順番に隣接交換を丁寧にトレースする。「パスN回後」「全体が完成するまでのパス数」を問う問題もあるため、各パス後の状態を縦に並べて書く習慣をつけてください。
---
問題3-2:選択ソートの動作
配列 [6, 2, 9, 1, 5] を選択ソート(昇順)で並び替えるとき、2パス目が終了した直後の配列の状態として正しいものはどれか。
ただし選択ソートの1パスとは「未ソート部分の最小値を探して先頭要素と交換する」操作とする。
選択肢:
- ア [1, 2, 5, 6, 9]
- イ [1, 2, 9, 6, 5]
- ウ [1, 2, 6, 5, 9]
- エ [1, 2, 6, 9, 5]
正答: イ([1, 2, 9, 6, 5])
ハンドトレース:
| パス | 未ソート部 | 最小値 | 交換位置 | 配列の状態 |
|---|---|---|---|---|
| 初期 | — | — | — | [6, 2, 9, 1, 5] |
| 1パス | [6,2,9,1,5] | 1(a[4]) | a[1]↔a[4] | [1, 2, 9, 6, 5] |
| 2パス | [2,9,6,5] | 2(a[2]) | 自身(交換なし) | [1, 2, 9, 6, 5] |
解法のポイント: 2パス後に先頭2要素が確定([1, 2, ...])。未ソート部 [9, 6, 5] はまだ乱れたまま。「最小値がすでに正位置にある場合は自身と交換(= 変化なし)」という場合があることも覚えておいてください。
---
問題3-3:挿入ソートの挿入位置
配列 [3, 7, 1, 8, 4] を挿入ソート(昇順)で並び替えるとき、3要素目(a[3]=1)を挿入した直後の配列の状態として正しいものはどれか。
ただし挿入ソートの各ステップとは「未ソート部の先頭要素を、ソート済み部の正しい位置に挿入する」操作とする。
選択肢:
- ア [1, 3, 7, 8, 4]
- イ [1, 3, 7, 4, 8]
- ウ [3, 1, 7, 8, 4]
- エ [1, 7, 3, 8, 4]
正答: ア([1, 3, 7, 8, 4])
ハンドトレース:
| ステップ | 操作 | 配列の状態 |
|---|---|---|
| 初期 | — | [3, 7, 1, 8, 4] |
| a[2]=7を挿入 | [3]にソート済み。7 > 3なのでそのまま | [3, 7, 1, 8, 4] |
| a[3]=1を挿入 | [3,7]にソート済み。1 < 7 → 7を右シフト。1 < 3 → 3を右シフト。先頭に1を挿入 | [1, 3, 7, 8, 4] |
解法のポイント: 挿入ソートは「ソート済み部を後ろから見て挿入位置を探す」動作です。1は3・7の両方より小さいため先頭(インデックス1)に挿入され、3と7が1つずつ右にシフトします。a[4]・a[5](8・4)はまだ未処理です。
---
問題3-4:ソートアルゴリズムの計算量比較
次の3つのソートアルゴリズムの最悪計算量(最も時間がかかるケース)を比較したとき、正しいものはどれか。
- バブルソート
- 選択ソート
- 挿入ソート(逆順配列の場合)
選択肢:
- ア 3つとも O(N) で同じ
- イ 3つとも O(N²) で同じ
- ウ バブルが最も速く、挿入が最も遅い
- エ 挿入が最も速く、選択が最も遅い
正答: イ(3つとも O(N²) で同じ)
解説: バブルソート・選択ソート・挿入ソートは全て最悪計算量 O(N²) です。N個の要素に対して最大 N×(N-1)/2 回の比較が必要なことが共通しています。ただし「平均的なケース」では挿入ソートがバブルよりも交換回数が少ない傾向があります。
計算量比較表(参考):
| アルゴリズム | 最良 | 平均 | 最悪 |
|---|---|---|---|
| バブルソート | O(N) | O(N²) | O(N²) |
| 選択ソート | O(N²) | O(N²) | O(N²) |
| 挿入ソート | O(N) | O(N²) | O(N²) |
| クイックソート | O(N log N) | O(N log N) | O(N²) |
| マージソート | O(N log N) | O(N log N) | O(N log N) |
解法のポイント: 科目BではO(N²) vs O(N log N) の区別が問われることがあります。基本3ソートはO(N²)、クイックソート(平均)・マージソートはO(N log N)という整理で覚えておいてください。
---
パターン4:データ構造操作系(4問)
スタック(LIFO・後入れ先出し)とキュー(FIFO・先入れ先出し)の push/pop・enqueue/dequeue 操作を追います。スタックは縦の積み上げ、キューは横の列として図示することが最速のトレース方法です。
---
問題4-1:スタック操作の結果
スタックに対して次の操作を順番に実行したとき、最後にポップした値はいくつか。
操作順:push(5) → push(3) → push(8) → pop() → push(2) → pop()
選択肢:
- ア 2
- イ 3
- ウ 5
- エ 8
正答: ア(2)
スタック状態の追跡:
| 操作 | スタック状態(上が最新) | pop の戻り値 |
|---|---|---|
| 初期 | [] | — |
| push(5) | [5] | — |
| push(3) | [5, 3] | — |
| push(8) | [5, 3, 8] | — |
| pop() | [5, 3] | 8(取り出し) |
| push(2) | [5, 3, 2] | — |
| pop() | [5, 3] | 2(最後の取り出し) |
解法のポイント: スタックは「後入れ先出し(LIFO: Last In First Out)」。push(8)後にpop()で8が出て、その後push(2)→pop()で2が出ます。「最後にポップした値」を問われているので2が正答。スタックの状態を図の縦積みで追うと混乱が防げます。
---
問題4-2:キュー操作の結果
キューに対して次の操作を順番に実行したとき、2回目のdequeue() が返す値はいくつか。
操作順:enqueue(1) → enqueue(4) → enqueue(7) → dequeue() → enqueue(2) → dequeue()
選択肢:
- ア 1
- イ 2
- ウ 4
- エ 7
正答: ウ(4)
キュー状態の追跡(左が先頭・先に出る側):
| 操作 | キュー状態(左が先頭) | dequeue の戻り値 |
|---|---|---|
| 初期 | [] | — |
| enqueue(1) | [1] | — |
| enqueue(4) | [1, 4] | — |
| enqueue(7) | [1, 4, 7] | — |
| dequeue() | [4, 7] | 1(1回目) |
| enqueue(2) | [4, 7, 2] | — |
| dequeue() | [7, 2] | 4(2回目) |
解法のポイント: キューは「先入れ先出し(FIFO: First In First Out)」。最初に入れた1が最初に出て、次に入れた4が2回目のdequeueで出ます。enqueue(2)は後から追加されるため4より後になります。キューを横の列として図示し、左(先頭)から取り出す図で追うと直感的に理解できます。
---
問題4-3:スタックを使った数式評価(後置記法)
後置記法(逆ポーランド記法)の式 「3 4 + 2 * 5 -」 をスタックを使って評価したとき、最終結果はいくつか。
後置記法の評価規則:数値はスタックにプッシュ、演算子が来たらスタックから2つポップして演算し結果をプッシュ。
選択肢:
- ア 9
- イ 14
- ウ 9
- エ 14
正答: ア(9)
スタック状態の追跡:
| トークン | 操作 | スタック状態 |
|---|---|---|
| 3 | push(3) | [3] |
| 4 | push(4) | [3, 4] |
| + | pop→4, pop→3, push(3+4=7) | [7] |
| 2 | push(2) | [7, 2] |
| * | pop→2, pop→7, push(7×2=14) | [14] |
| 5 | push(5) | [14, 5] |
| - | pop→5, pop→14, push(14-5=9) | [9] |
解法のポイント: 後置記法はスタックで自然に評価できます。「演算子が来たら2つポップし、演算し、結果をプッシュ」という操作を繰り返すだけです。引き算・割り算は順序に注意(最後にポップした値が被演算子の右辺)。この問題形式は本番でも出題実績があります。
---
問題4-4:連結リストの操作
次の連結リスト操作の疑似言語コードを実行したとき、リストの最後の要素の値はいくつか。
初期状態:head → [5] → [3] → [7] → null
```
/ newNodeを値12で作成し、リストの末尾に追加する /
新ノード作成: newNode.val ← 12, newNode.next ← null
整数型ポインタ: current ← head
(current.next ≠ null) の間,繰り返す
current ← current.next
を繰り返す
current.next ← newNode
```
選択肢:
- ア 5
- イ 7
- ウ 12
- エ null
正答: ウ(12)
トレース:
| ステップ | current | current.next |
|---|---|---|
| 初期 | head→[5] | [3] (≠null) |
| 反復1 | [3] | [7] (≠null) |
| 反復2 | [7] | null → ループ終了 |
| 末尾挿入 | [7].next ← newNode(12) | リスト:[5]→[3]→[7]→[12] |
解法のポイント: current.next が null になるまでループで末尾を探し、末尾ノードの next に新ノードを接続するパターン。連結リストの「末尾追加」の典型コードです。先頭追加(head の付け替え)・途中挿入との違いを理解しておいてください。
---
パターン5:再帰関数・木構造(4問)
科目Bの最難関パターン。関数が自分自身を呼び出す再帰の実行をコールスタックで追います。本番で時間が足りない場合は後回しにする判断も必要ですが、典型パターンをマスターすれば得点源になります。
---
問題5-1:再帰による階乗計算
疑似言語コード
```
整数型関数: factorial(整数型: n)
もし (n = 0) ならば
return 1
そうでなければ
return n * factorial(n - 1)
を実行する
```
`factorial(4)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 4
- イ 10
- ウ 24
- エ 120
正答: ウ(24)
コールスタックのトレース:
| 呼び出し | n | 条件 | 展開 |
|---|---|---|---|
| factorial(4) | 4 | 4≠0 | return 4 × factorial(3) |
| factorial(3) | 3 | 3≠0 | return 3 × factorial(2) |
| factorial(2) | 2 | 2≠0 | return 2 × factorial(1) |
| factorial(1) | 1 | 1≠0 | return 1 × factorial(0) |
| factorial(0) | 0 | 0=0 | return 1 |
帰りがけ(戻り値の計算):
```
factorial(0) → 1
factorial(1) → 1 × 1 = 1
factorial(2) → 2 × 1 = 2
factorial(3) → 3 × 2 = 6
factorial(4) → 4 × 6 = 24
```
解法のポイント: 再帰は「行きがけ(呼び出し)」と「帰りがけ(戻り値の計算)」の2段階で追います。n=0が基底ケース(再帰の終了条件)。コールスタックを縦に書いて、帰りがけに下から掛け算を積み上げる手順で確実に解けます。
---
問題5-2:フィボナッチ数列
疑似言語コード
```
整数型関数: fib(整数型: n)
もし (n <= 1) ならば
return n
そうでなければ
return fib(n - 1) + fib(n - 2)
を実行する
```
`fib(6)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 6
- イ 8
- ウ 11
- エ 13
正答: イ(8)
フィボナッチ数列の値(底から積み上げ):
| n | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| fib(n) | 0 | 1 | 1 | 2 | 3 | 5 | 8 |
解法のポイント: fib(n) = fib(n-1) + fib(n-2) で、fib(0)=0, fib(1)=1 が基底ケース。数列を地道に積み上げると fib(6)=8 と確認できます。コールスタックで全展開すると非常に多くの呼び出しが発生するため、本番では「数列の値を0から順番に表で埋める」手法が圧倒的に速いです。
---
問題5-3:再帰による配列合計
疑似言語コード
```
整数型配列: a ← [2, 4, 6, 8, 10]
整数型関数: sum(整数型: i, 整数型: n)
もし (i > n) ならば
return 0
そうでなければ
return a[i] + sum(i + 1, n)
を実行する
```
`sum(1, 5)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 20
- イ 28
- ウ 30
- エ 32
正答: ウ(30)
コールスタックのトレース:
| 呼び出し | i | i > 5? | return |
|---|---|---|---|
| sum(1,5) | 1 | NO | a[1] + sum(2,5) = 2 + sum(2,5) |
| sum(2,5) | 2 | NO | 4 + sum(3,5) |
| sum(3,5) | 3 | NO | 6 + sum(4,5) |
| sum(4,5) | 4 | NO | 8 + sum(5,5) |
| sum(5,5) | 5 | NO | 10 + sum(6,5) |
| sum(6,5) | 6 | YES | return 0 |
帰りがけ: 10+0=10 → 8+10=18 → 6+18=24 → 4+24=28 → 2+28=30
解法のポイント: 再帰で配列合計を計算するパターン。終了条件「i > n → return 0」が重要。帰りがけに積み上げる値は a[1]+a[2]+...+a[5] = 2+4+6+8+10 = 30 です。
---
問題5-4:二分木の深さ(DFS)
疑似言語コード(二分木の最大深さを求める)
```
/ ノードは val(値)・left(左の子ノード)・right(右の子ノード)を持つ /
/ null はノードが存在しないことを示す /
整数型関数: maxDepth(ノード型: node)
もし (node = null) ならば
return 0
そうでなければ
整数型: leftDepth ← maxDepth(node.left)
整数型: rightDepth ← maxDepth(node.right)
return max(leftDepth, rightDepth) + 1
を実行する
```
以下の二分木で `maxDepth(root)` を実行したとき、戻り値はいくつか。
```
1
/ \
2 3
/ \
4 5
\
6
```
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: イ(4)
深さのトレース:
```
maxDepth(1)
├─ maxDepth(2)
│ ├─ maxDepth(4) → null,null → max(0,0)+1 = 1
│ └─ maxDepth(5)
│ ├─ maxDepth(null) → 0
│ └─ maxDepth(6) → null,null → max(0,0)+1 = 1
│ → max(0,1)+1 = 2
│ → max(1,2)+1 = 3
└─ maxDepth(3) → null,null → max(0,0)+1 = 1
→ max(3,1)+1 = 4
```
解法のポイント: 木の最大深さは左右の子の深さの大きい方に1を足す再帰で求められます。最長経路は 1→2→5→6 の4ノード分。木構造の再帰問題は「葉(null)から戻る」帰りがけの計算を丁寧に追うことが重要です。本番では時間がかかるため、まず深い経路を目で確認し「何ノード分か」を数える目算で答えを絞ることも有効です。
---
5パターン総まとめ
| パターン | 問題数 | キーワード | 最重要テクニック |
|---|---|---|---|
| 1. 線形探索・集計 | 4問(最頻出) | 合計・最大値・カウント | 変数表を手書き。i と集計変数の2列 |
| 2. 二分探索 | 4問 | lo・hi・mid | 3変数を縦に並べて書く。終了条件に注意 |
| 3. ソート | 4問 | バブル・選択・挿入 | 各パス後の配列状態を縦に並べる |
| 4. データ構造 | 4問 | スタック(LIFO)・キュー(FIFO) | スタックは縦積み・キューは横列で図示 |
| 5. 再帰・木構造 | 4問(最難) | 階乗・フィボナッチ・DFS | コールスタックを縦積み。帰りがけを丁寧に |
戦略: パターン1〜4(16問)を確実に習得すると、アルゴリズム16問中12〜14問を取れる実力がつきます。パターン5(再帰)は+α。本番で時間が足りない場合は再帰問題を後回しにする判断も正しいです。
FE科目Bの攻略法(パターン別戦略)を詳しく読む / FE過去問548問(本番形式演習) / FE完全合格ガイド / 科目A頻出論点と分野別攻略 / FE合格率と試験統計
---
本記事はIPA「基本情報技術者試験 出題範囲・シラバス」および「疑似言語の仕様」(https://www.ipa.go.jp/shiken/kubun/fe.html)をもとに、合格ナビ編集部がオリジナルの練習問題を作成したものです。本番試験問題の転載ではありません。架空の監修者はいません。