JavaScriptで数値が2つの平方数の和として表せるか判定する方法
平方数(完全平方数)とは?
数学において、ある自然数が別の自然数とそれ自身との積で表されるとき、その数を平方数(完全平方数)と呼びます。
例えば、9、16、81、289 はすべて平方数です。
- 9 = 3 × 3
- 16 = 4 × 4
- 81 = 9 × 9
- 289 = 17 × 17
問題の定義
自然数 num を引数として受け取るJavaScript関数を作成します。この関数は、次の条件を満たす2つの数 m と n が存在するかどうかを判定する必要があります。
(m * m) + (n * n) = num
そのような数の組み合わせが存在すれば true を、存在しなければ false を返します。
例
入力が以下の場合:
const num = 389;
出力は次のようになります:
const output = true;
これは、389 = (17 × 17) + (10 × 10) と表せるためです。つまり、17² + 10² = 289 + 100 = 389 が成立します。
解法:双方向ポインタ(Two Pointer)を使ったアプローチ
この問題を効率的に解くには、双方向ポインタ(ツーポインター)テクニックが有効です。手順は以下の通りです。
- 左ポインタ
leftを 0 に、右ポインタrightを √num の切り捨て値に初期化します。 left * left + right * rightがnumと一致すればtrueを返します。- 合計が
numより小さければleftを増やし、大きければrightを減らします。 - ポインタが交差するまで繰り返し、見つからなければ
falseを返します。
この方法では O(√n) の計算量で判定できるため、大きな数でも高速に処理できます。
サンプルコード
const num = 389;
const canSumSquares = (num = 2) => {
let left = 0, right = Math.floor(Math.sqrt(num));
while (left <= right) {
if (left * left + right * right === num) {
return true;
} else if (left * left + right * right < num) {
left++;
} else {
right--;
}
}
return false;
};
console.log(canSumSquares(num));実行結果
コンソールには次のように出力されます:
true
コードのポイント解説
Math.floor(Math.sqrt(num)):右ポインタの初期値を設定しています。√num を超える整数を二乗しても num より大きくなるため、探索範囲はこれで十分です。left <= right:同じ数を2回使うケース(例:50 = 5² + 5²)にも対応できるよう、等号を含めています。- 計算量:ループは最大 √n 回しか回らないため、時間計算量は O(√n)、空間計算量は O(1) と非常に効率的です。
まとめ
双方向ポインタを使うことで、ある自然数が2つの平方数の和で表せるかどうかを簡潔かつ高速に判定できます。この手法は「Two Sum」系の問題にも応用できる汎用的なテクニックなので、ぜひ覚えておきましょう。
-
JavaScriptで配列をnum個に分割!部分配列の最大合計を最小化する二分探索アルゴリズム
問題概要負でない整数のみを含む配列 arr を第1引数に、整数 num(num < arr.length)を第2引数として受け取るJavaScript関数を作成します。関数の目的は、元の配列を空でない連続した部分配列にちょうど num 個に分割することです。その際、各部分配列の合計値の中で最大のものが最小になるように分割し、その最小化された「最大合計」を戻り値として返します。入力例const arr = [5, 1, 4, 8, 7];const num = 2;出力例const output = 15;出力の解説長さ5の配列を2つの部分配列に分割する方法は全部で4通りあります。それぞれ
-
JavaScriptで2つの二分探索木(BST)のノード値の合計が目標値に一致するか判定する方法
問題 JavaScriptの関数を作成します。この関数は、第1引数として1つ目の二分探索木のルートroot1を、第2引数として2つ目の二分探索木のルートroot2を受け取り、さらに第3引数として整数targetを受け取ります。 この関数は、「1つ目の木の中のあるノード」と「2つ目の木の中のあるノード」の値を足し合わせた結果がtargetと一致するようなペアが存在する場合にのみtrueを返し、存在しない場合はfalseを返す必要があります。 たとえば、次のような入力が与えられたとします。 const target = 23; 2つのBSTの例 この場合の出力は次のようになります。 const