JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで正方行列を90度回転させる方法|追加メモリ不要のin-place実装

n × n の二次元配列(正方行列)を受け取り、それを時計回りに90度回転させるJavaScript関数を作成してみましょう。

ここでの重要な条件は、余分な配列を新しく確保せずに(in-placeで)処理を行うことです。つまり、元の配列そのものを直接書き換えて回転を実現します。

入力例と期待される出力

たとえば、次のような3×3の行列が入力だった場合を考えます。

const arr = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

この行列を時計回りに90度回転すると、結果は次のようになります。

const output = [
    [7, 4, 1],
    [8, 5, 2],
    [9, 6, 3],
];

回転の考え方:転置+行の反転

正方行列を時計回りに90度回転するには、以下の2ステップが有効です。

手順1:行列を転置する
行と列を入れ替えます。具体的には、要素 arr[i][j]arr[j][i] を交換します。対角線より上側だけを走査すれば十分なので、内側のループは j = i + 1 から開始します。

手順2:各行を左右に反転する
転置後の各行について、左端と右端の要素を順に交換していきます。各行の中央まで処理できればよいので、内側のループは arr.length / 2 まで走査します。

この2つの操作を組み合わせることで、追加の配列を一切使わずに回転が完了します。

実装コード

要素の交換には、ES2015以降で使える分割代入(デストラクチャリング)によるスワップを利用しています。これにより一時変数を用意せずに済み、コードもすっきりします。

const arr = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

const rotateArray = (arr = []) => {
    // 手順1:行列を転置する(行と列を入れ替え)
    for (let rowIndex = 0; rowIndex < arr.length; rowIndex += 1) {
        for (let columnIndex = rowIndex + 1; columnIndex < arr.length;
        columnIndex += 1) {
            [
                arr[columnIndex][rowIndex],
                arr[rowIndex][columnIndex],
            ] = [
                arr[rowIndex][columnIndex],
                arr[columnIndex][rowIndex],
            ];
        }
    }

    // 手順2:各行を左右反転する
    for (let rowIndex = 0; rowIndex < arr.length; rowIndex += 1) {
        for (let columnIndex = 0; columnIndex < arr.length / 2;
        columnIndex += 1) {
            [
                arr[rowIndex][arr.length - columnIndex - 1],
                arr[rowIndex][columnIndex],
            ] = [
                arr[rowIndex][columnIndex],
                arr[rowIndex][arr.length - columnIndex - 1],
            ];
        }
    }
};

rotateArray(arr);
console.log(arr);

実行結果

コンソールには次のように出力されます。

[ [ 7, 4, 1 ], [ 8, 5, 2 ], [ 9, 6, 3 ] ]

計算量について

このアルゴリズムの時間計算量は O(n²) です。行列のすべての要素を定数回ずつ訪問するため、これ以上効率化することはできません。また、追加の配列を確保しないため空間計算量は O(1) となり、「in-placeで回転せよ」という条件を満たしています。

  1. JavaScriptで2の平方根(√2)を取得する方法

    JavaScriptで2の平方根(√2)を取得するには、Mathオブジェクトが持つSQRT2プロパティを使用します。このプロパティは定数として定義されており、2の平方根である約 1.414 の値を返します。Math.SQRT2は読み取り専用の定数であり、自分で計算する必要がないため、コードの可読性と精度の両面でメリットがあります。サンプルコード以下のコードを実行すると、JavaScriptで2の平方根の値を取得して表示できます。<html>    <head>       <title>JavaScript

  2. JavaScriptで学ぶAVL木の回転操作|LL・RR・LR・RL回転を図解&コード付きで解説

    AVL木は、ノードの挿入や削除によってバランスが崩れた際に、自己平衡性を保つために以下の4種類の回転(ローテーション)操作を実行します。 左回転(Left Rotation)右回転(Right Rotation)左右回転(Left-Right Rotation)右左回転(Right-Left Rotation) 最初の2つは「単回転」、後の2つは「二重回転」に分類されます。木が不平衡となるためには、少なくとも高さ2の木が必要です。ここではシンプルな木を例に、それぞれの回転操作を順番に解説していきます。 左回転(Left Rotation) あるノードの「右部分木のさらに右部分木」にノードを挿