世界を動かす技術を、日本語で。

ビッグO記法の視覚的入門

2025年8月24日原文(samwho.dev)

概要

  • Big O記法 は、入力サイズに対するアルゴリズムの性能や成長率を表現する手法
  • O(1) (定数時間)、 O(log n) (対数時間)、 O(n) (線形時間)、 O(n^2) (二乗時間)など、代表的な4つのカテゴリを解説
  • sum関数bubble sortbinary search などの具体例で理解を深める構成
  • 最悪ケース を基準とした計算量評価が基本
  • 実践的な改善策 や注意点も紹介

Big O記法の基礎

  • Big O記法 は、関数やアルゴリズムの 性能(計算量) を、実際の処理時間ではなく 入力サイズの増加に対する成長率 で表現
  • 時間計測ではなく、 入力nが増えたときに処理量がどのように増えるか を分析
  • 主に プログラムやアルゴリズムの効率性比較、大規模データへの対応力評価に利用
  • O(1) (定数)、 O(log n) (対数)、 O(n) (線形)、 O(n^2) (二乗)など、成長率で分類
  • 最悪ケース (worst-case)を基準に評価するのが一般的

線形時間(O(n))の例:sum関数

  • sum(n)関数は 1からnまでの合計値をforループ で計算
  • 入力nが2倍になると、 実行時間もほぼ2倍 となる特徴
  • このように 入力サイズに比例して処理回数が増加 するものを O(n) と呼称
  • O(n) の「O」は Order(成長の階級) を意味し、 O(n) は「nの階級の成長」を示す
  • Big O記法 では 最小の項のみ を記述し、O(2n)やO(n+1)とは書かない

定数時間(O(1))の例:数式によるsum関数

  • sum(n)を数式(n*(n+1))/2で計算すると、 入力サイズnに関係なく一定回数の演算 で完了
  • どんなnでも 処理時間はほぼ変わらない ため、 O(1) (定数時間)と呼ぶ
  • O(1) は「瞬時」ではなく「入力サイズに依存しない」ことを意味
  • 実際の処理時間が長い場合もあり得る点に注意

二乗時間(O(n^2))の例:bubble sort

  • bubble sort は、隣接要素を比較・交換しながら 複数回ループ して整列
  • 最悪ケース(逆順配列)では n回のループをn回繰り返す ため、 O(n^2) (二乗時間)となる
  • 入力データの並び順 によって実行回数が変わるが、Big O記法では 最悪ケース を基準
  • O(n^2) は大量データに弱いアルゴリズムの典型例

対数時間(O(log n))の例:binary search

  • binary search は、整列済み配列から 中央値で範囲を半分に絞り込む探索法
  • 各ステップごとに探索範囲が1/2 になるため、必要なステップ数は log₂n に比例
  • 例:1~1,000,000,000の中から1つを当てる場合でも 最大31回の比較 で済む
  • O(log n) は大規模データでも極めて効率的なアルゴリズムの代表

実践的なBig O活用例と注意点

リスト内検索

  • 配列で値を探すcontains(items, target)O(n) (線形探索)
  • 頻繁に検索する場合、 Set構造 を使えば O(1) で高速化可能
  • ただし、new Set(items)の生成自体は O(n) である点に注意

インデックス付きループの罠

  • ループ内でitems.indexOf(item)を呼ぶと、 O(n)の探索×n回=O(n^2) となり非効率
  • ループインデックスやforEach((item, index) => ...)を活用し、 O(n) へ最適化

再帰とキャッシュ

  • 再帰的な計算 (例:factorial)は O(n) だが、同じ計算を繰り返す場合は メモ化(キャッシュ) で高速化可能
  • 再帰呼び出しの最適化やキャッシュ利用で 計算量の削減 を図る

まとめ

  • Big O記法 は、アルゴリズムのスケーラビリティを理解・比較するための 強力な指標
  • O(1)、O(log n)、O(n)、O(n^2) の違いを体感し、 適切なアルゴリズム選択・改善 が可能
  • 最悪ケースの計算量 を意識しつつ、 現実的なパフォーマンス も考慮した設計が重要

Hackerたちの意見

ビッグO記法を身につけるための一番効果的な方法は、日常の経験に結びつけることだと思う。

いいね!ピンを送ったけど、ちゃんと届いてるといいな。ちょっとドーパミンが出た気分 ;-)

届いたよ、ありがとう!<3

ダイナミックなビジュアライゼーションが内容を理解するのにめっちゃ役立つね。こんなレッスンをもっと作ってほしい!

気に入ってもらえて嬉しい!<3

電気工学を学んでたけど、ビッグO記法がちゃんと説明されたことがなかった気がする。毎回紹介されるときに見逃してたのかな?いつも「これくらいは知ってるよね」って感じで流されてた。どのレベルの数学やコンピュータサイエンスが普通はこれを紹介するのか気になる。

僕の大学には「アルゴリズム分析」の授業があって、これはCS専攻には必須だったんだ。いろんな証明方法もカバーしてたけど、これは3年生か4年生の授業だったよ。1年生の終わりまでには、ある程度この概念に慣れてることが期待されてたと思う(なんか自然に覚える感じでね)。

関数 f(x) が O(g(x)) であると言われるのは、f(x)/g(x) が有界で、つまり C という値があって、すべての x に対して f(x)/g(x) < C になるときだよ。コンピュータサイエンスでは、f(x) はしばしばアルゴリズムを完了させるときの特定の操作の数みたいな複雑度関数になることが多い。

コンピュータサイエンス101。1年生のときに学んだよ。実際、そんなに難しいことはないんだ。ただ、アルゴリズムの入力数が増えるにつれて、操作の数がどう成長するかを説明してるだけだから。見た目は怖いけど、すごくシンプルでわかりやすいよ。

あなたのブログはいつも情報満載のビジュアライゼーションがあって、こういう概念を理解しやすくしてくれる!どのツールを使って作ってるの?

コードはここにあるよ: https://github.com/samwho/visualisations。今回は基本的なJS、CSS、HTMLしか使ってないんだ。確か、唯一の外部依存はJavaScriptをASTにパースするためのやつだったかな。

ビッグO記法についてのスレが立つたびに、誰かがアニメ「ザ・ビッグO」との関連をわかりやすく説明してくれることを期待してる。あのショーで何が起こったのか、まだ理解できてないんだよね。

Hacker Newsで議論の続きを見る