1. [100,4,200,1,3,2] -> 4
  2. [9,1,4,7,3,-1,0,5,8,-1,6] -> 7
  3. [1] -> 1
  4. [10, 30, 20] -> 1
  5. [0,3,7,2,5,8,4,6,0,1] -> 9
  6. [1,2,0,1] -> 3
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
最長連続部分列

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

最長連続部分列

同じ列を、何度も歩き直している

[100, 4, 200, 1, 3, 2] の中で、連続する整数が一番長く続くのは 1, 2, 3, 4 の 4 個です。並んでいる順は関係ありません。

素直に書くと、各要素から右へ「次の数はあるか」と伸ばしていく形になります。この配列で歩数を数えてみます。1 から 4 歩、2 から 3 歩、3 から 2 歩、4 から 1 歩、100 と 200 から 1 歩ずつ。合わせて 12 歩です。答えは 4 なのに 12 歩かかりました。

長さ L の列があると、そこだけで L * (L + 1) / 2 歩です。1000 個が 1 本に繋がっていたら、答えを出すのに 50 万歩かかります。

途中から歩き出しても、新しいことは分からない

2 から歩き出して分かるのは「2, 3, 4 で 3 個」ということだけです。これは 1 から歩いたときに、途中で通り過ぎた話です。3 からも 4 からも同じで、列の途中を起点にした探索は、必ず誰かの歩みの一部にしかなりません。

意味があるのは、列の先頭から歩き出したときだけです。では、ある値が列の先頭かどうかは、どう見分けるか。その値より 1 小さい値が、どこにも入っていないときです。

  • 1 より 1 小さい 0 は入っていない。だから 1 は先頭
  • 2 より 1 小さい 1 は入っている。だから 2 からは歩かない

先頭だけを起点にすれば、各値が触られるのは「先頭かどうかの確認」と「どれかの列の途中として通られるとき」の 2 回だけです。12 歩が 4 歩に戻り、1000 個でも 1000 歩で終わります。

「その値があるか」を一瞬で聞ける入れ物

この作戦は「1 小さい値はあるか」を要素の数だけ聞きます。聞くのが遅ければ、せっかく歩数を減らしても意味がありません。配列に聞くと端から探すので、件数が増えるほど遅くなります。

JavaScript

// 別題材 — 招待済みかどうかを聞く const invited = new Set(emails); invited.has("aoi@example.com"); // 何件あっても待たされない

Set は入れた値をそのまま覚えていて、「あるか」の問いに件数と関係のない速さで答えます。同じ値を 2 回入れても 1 つにまとまるので、重複を含む配列でも数がずれません。

空の配列と、長さの初期値

配列が空なら答えは 0 です。最長の長さを入れる変数を 1 から始めると、1 個も無い配列に 1 を返してしまいます。0 から始めて、列を歩いたときだけ更新してください。

歩いた長さの数え方も、1 つずれやすいところです。先頭の値そのものを 1 個目と数えてから、次の値が見つかるたびに増やします。先頭を数え忘れると、答えが常に 1 少なくなります。

要件

  1. set を使って O(n) (期待計算量) で解く
  2. 重複や負の数が含まれていても正しく動作すること
  3. 空配列の場合は 0 を返す

入出力例

longestConsecutive([100,4,200,1,3,2]) → 4 longestConsecutive([9,1,4,7,3,-1,0,5,8,-1,6]) → 7 longestConsecutive([1]) → 1 longestConsecutive([10,30,20]) → 1 longestConsecutive([0,3,7,2,5,8,4,6,0,1]) → 9 longestConsecutive([1,2,0,1]) → 3

ヒント

全要素を `set` に入れて、`v - 1` が `set` にない要素だけを起点に走査する

起点判定を入れないとシーケンスを何度も走査して `O(n^2)` になる

最長を更新する `best` は `0` で初期化しておくと空配列の戻り値が自然になる

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 集合の積 (intersection)

    2 つの整数配列の共通要素 (集合の積) を `set` で求めて、重複なしの昇順リストで返す。

  • 第4章まとめクイズ

    ハッシュとセットの計算量・性質・使いどころを 4 択クイズで総点検する。

  • グラフ BFS で連結成分サイズを求める

    幅優先探索 (BFS) を使って、指定した頂点を含む連結成分のノード数を返す関数を実装する。

  • 編集距離 (レーベンシュタイン距離)

    2 つの文字列を一致させるために必要な最小編集回数を、二次元 DP で求める古典問題に挑戦します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 配列サイズ固定の同型データの集まり
  • 変数データに名前をつけて参照する仕組み
  • 計算量入力サイズに対する処理時間の伸び方
main.py
学習モード
エディタを読み込んでいます

メモ

最長連続部分列

⌘S で保存