JavaScriptの再帰で解く!行列を螺旋状に巡回するスパイラルトラバーサル問題
問題の概要
まず、次のような2次元配列を考えてみましょう。
const arr = [ [1, 2, 3, 4], [12,13,14,5], [11,16,15,6], [10,9, 8, 7] ];
この配列は正方行列(行数と列数が等しいマトリックス)であることが前提となっています。
私たちの課題は、この配列を受け取り、外側から内側へ渦巻き状に要素を取り出して新しい配列を構築するJavaScript関数を書くことです。カタツムリが這い残した跡(スネイルトレイル)のように、マトリックスの外周をぐるりと一周しながら、徐々に中心へ収束していきます。
したがって、上記の配列に対する期待される出力は次のようになります。
const output = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
アプローチ:再帰を使う
この問題は再帰(リカージョン)を使うことで、シンプルかつエレガントに解くことができます。基本的な考え方は以下の通りです。
- マトリックスの最上行を取り出し、結果の配列に連結する
- 残りのマトリックスを反時計回りに90度回転させる
- マトリックスの行数が1になるまで、この操作を繰り返す
「上の一行を剥がして、残りを回転する」という操作を繰り返すだけで、自然に螺旋順の並びが得られるのがポイントです。
コード例
実際のコードは次のようになります。
const arr = [
[1, 2, 3, 4],
[12,13,14,5],
[11,16,15,6],
[10,9, 8, 7]
];
const spiralForm = arr => {
return arr.length > 1 ?
arr.splice(0,1)[0]
.concat(spiralForm(arr[0].map((c, i) => {
return arr.map(r => r[i]);
})
.reverse())) :
arr[0]
}
console.log(spiralForm(arr));出力
このコードを実行すると、コンソールには次のように出力されます。
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ]
コードの仕組みを分解してみる
- ベースケース(終了条件): arr.length が1以下になったら、残りの arr[0](最後の行や中央の要素)をそのまま返します。ここで再帰が停止します。
- 最上行の取り出し: splice(0, 1)[0] によって先頭の行を取り出します。これが螺旋の一段目に相当します。
- 90度回転: 残りの配列に対して map() で各列を抽出し、reverse() で列の順序を反転することで、マトリックス全体を反時計回りに90度回転させます。これにより「右端の列」が新しい「最上行」になります。
- 連結と再帰呼び出し: 取り出した行と、回転後のマトリックスに対する再帰呼び出しの結果を concat() でつなぎ合わせて返します。
最初のステップでは [1, 2, 3, 4] が取り出され、残りの3×4マトリックスが回転されて [5, 6, 7] が次の最上位の行になります。以降も同様に 8、9、10…と外周から順に要素が剥がれていき、最終的に完全な螺旋順の1次元配列が完成します。
注意点:splice() の副作用
この実装では splice() を使用しているため、引数として渡された元の配列が破壊的に変更される点に注意が必要です。元の配列を後続の処理でも使いたい場合は、あらかじめ [...arr] や arr.map(row => [...row]) などでコピーを作成してから関数に渡すようにしましょう。
-
JavaScriptで配列を空にする方法まとめ【3つの手法と使い分けのポイント】
JavaScriptで配列を空にする(初期化する)方法は複数あります。それぞれの手法には特徴や注意点があり、状況に応じて適切に使い分けることが重要です。この記事では、代表的な3つの方法と、それぞれのメリット・デメリットを詳しく解説します。まず、以下のような配列があると仮定します。let arr = [1, test, {}, 123.43];方法1:新しい空の配列で置き換えるarr = [];変数arrに新しい空の配列を再代入する方法です。最もシンプルかつ高速な手法として知られています。ただし注意点として、元の配列への参照がプログラムの他の場所に存在する場合、それらの参照は自動的に更新されませ
-
JavaScriptの基本配列メソッド解説!push・pop・shift・unshift・spliceの使い方を実例付きで紹介
JavaScriptには、配列を操作するための便利な組み込みメソッドが数多く用意されています。その中でも特によく使われるのが、要素の追加や削除を行う以下の5つの基本メソッドです。 JavaScriptの主要な配列メソッド一覧 メソッド説明 Array.push()配列の末尾に要素を追加します。 Array.pop()配列の末尾から要素を取り除きます。 Array.unshift()配列の先頭に要素を追加します。 Array.shift()配列の先頭から要素を取り除きます。 Array.splice()配列内の任意の位置で要素の追加・削除を行います。 これらのメソッドは、配列の