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

JavaScriptでマトリックス内のラッキーナンバーをすべて見つける方法

ラッキーナンバーとは?

「ラッキーナンバー」とは、行列(マトリックス)の中で、自分の行における最小値であり、同時に自分の列における最大値でもある要素のことを指します。

今回の課題は、整数の二次元配列を受け取るJavaScript関数を書くことです。この関数は、配列内に存在するすべてのラッキーナンバーを見つけ出し、新しい配列として返します。条件を満たす要素がひとつも存在しない場合は、空の配列を返します。

入力例と出力例

たとえば、次のような二次元配列が与えられたとしましょう。

const arr = [
    [5, 3, 7, 3],
    [4, 2, 67, 2],
    [2, 32, 7, 4],
    [2, 9, 45, 23]
];

この場合の出力は次のようになります。

const output = [];

このマトリックスには「行で最小かつ列で最大」という条件を満たす要素が存在しないため、結果は空の配列となります。

解き方のアプローチ

この問題を効率よく解くには、次の手順で考えます。

  • ステップ1:各列ごとの最大値をあらかじめ計算しておく。
  • ステップ2:各行の最小値を求める。
  • ステップ3:行の最小値が、その要素のある列の最大値と一致していれば、それはラッキーナンバー。結果の配列に追加する。
  • ステップ4:すべての行を調べ終えたら、結果の配列を返す。

コード例

以下が実際のコードです。

const arr = [
    [5, 3, 7, 3],
    [4, 2, 67, 2],
    [2, 32, 7, 4],
    [2, 9, 45, 23]
];
const luckyNumbers = (arr = []) => {
    const rows = arr.length;
    const cols = arr[0].length;

    // 各列の最大値を事前に計算しておく
    const colMax = [];
    for (let j = 0; j < cols; j++) {
        let max = -Infinity;
        for (let i = 0; i < rows; i++) {
            max = Math.max(max, arr[i][j]);
        }
        colMax.push(max);
    }

    // 行の最小値が、その列の最大値と一致するかをチェック
    const result = [];
    for (let i = 0; i < rows; i++) {
        const minRow = Math.min(...arr[i]);
        const pos = arr[i].indexOf(minRow);
        if (minRow === colMax[pos]) {
            result.push(minRow);
        }
    }
    return result;
};
console.log(luckyNumbers(arr));

実行結果

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

[]

コードの解説

ここからは、コードのポイントを順番に見ていきましょう。

1. 各列の最大値を事前に計算

最初の二重ループでは、各列 j に対して、その列に含まれる全要素の中から最大値を求め、colMax 配列に格納しています。こうすることで、後の判定処理のたびに列を何度も走査し直す必要がなくなります。

2. 行の最小値とその位置を特定

Math.min(...arr[i]) ではスプレッド構文を使って各行の最小値を取得し、indexOf() によってその最小値が何番目の列に位置するかを特定しています。

3. ラッキーナンバーの判定

行の最小値 minRow が、同じ列位置の最大値 colMax[pos] と一致すれば、その要素は「行で最小・列で最大」を同時に満たしているため、ラッキーナンバーとして結果に追加されます。

計算量について

この実装の時間計算量は O(m × n)(m は行数、n は列数)です。各要素の参照は高々2回程度で済むため、大きなマトリックスでも効率的に動作します。また、複数のラッキーナンバーが存在する場合にも、すべてを正しく収集して返せる点がこの実装の強みです。

  1. JavaScriptの数値(Number)の基本と実践サンプルコード

    JavaScriptでは、整数も小数もすべて「Number」型として扱われます。この記事では、数値変数の定義方法と、それらを使った簡単な演算の例を、動作するHTMLサンプルコードとともに紹介します。サンプルコード以下は、JavaScriptで数値を扱う基本的な例です。整数(22、99)と小数(1.523)を変数に格納し、ボタンをクリックすると画面に表示する仕組みになっています。<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport co

  2. JavaScriptで数列の和を計算する方法

    問題次のような級数の和を考えてみましょう。$$seq(n,\:p)=\displaystyle\sum\limits_{k=0}^{n}(-1)^{k}\times\:p\:\times 4^{n-k}\:\times\frac{2n-k}{k}$$この問題では、数値 n と p を引数として受け取り、seq(n, p) の計算結果を返すJavaScript関数を作成することが求められます。この級数は以下の要素で構成されています。(-1)k: kが偶数なら正、奇数なら負となる交互符号p: 固定の係数4n-k: 4の冪乗(2n-k)/k: kに応じて変化する倍率解決策forループを使って k =