【JavaScript】指定した数値より小さくなる2つの要素の合計の最大値を求める方法
この記事では、数値の配列 arr を第1引数、単一の数値 num を第2引数として受け取るJavaScript関数を作成します。
この関数の目的は、配列の中から「合計が num よりも小さくなるような2つの数値」を見つけ出し、その中で最大の合計値を返すことです。もし合計が num 未満になる2つの数値の組み合わせが存在しない場合は、-1 を返します。
問題の例
たとえば、入力となる配列と数値が以下の場合を考えてみましょう。
const arr = [34, 75, 33, 23, 1, 24, 54, 8]; const num = 60;
この場合、期待される出力は次のとおりです。
const output = 58;
これは、34 + 24 = 58 が「60より小さい合計」の中で最も大きな値だからです。他の組み合わせ(例:54 + 1 = 55、33 + 23 = 56など)は58に届きません。
解決アプローチ:ソート+ツーポインタ法
この問題は、配列を昇順にソートした上でツーポインタ(双方向ポインタ)を使うことで、O(n log n) の計算量で効率的に解くことができます。
- 先頭を指すポインタ
iと末尾を指すポインタjを用意します。 - 両者の合計が
numより小さければ、その合計は候補となるため最大値を更新し、より大きな合計を狙ってiを前に進めます。 - 合計が
num以上なら、合計を下げるためにjを後ろに下げます。 - ポインタが交差するまで繰り返し、最終的な最大値を返します。
コード例
const arr = [34, 75, 33, 23, 1, 24, 54, 8];
const num = 60;
const lessSum = (arr = [], num = 1) => {
arr.sort((a, b) => a - b);
let max = -1;
let i = 0;
let j = arr.length - 1;
while (i < j) {
let sum = arr[i] + arr[j];
if (sum < num) {
max = Math.max(max, sum);
i++;
} else {
j--;
 };
};
return max;
};
console.log(lessSum(arr, num));
実行結果
コンソールには以下のように出力されます。
58
補足ポイント
sort((a, b) => a - b)を使うことで、文字列比較による誤った並び替えを防ぎ、正しく数値の昇順ソートが行われます。- 条件を満たすペアが一度も見つからなかった場合、初期値
-1がそのまま返されるため、要件どおりの動作になります。 - 全ペアを総当たりで調べる方法(O(n²))でも解けますが、ソート後のツーポインタ法の方が大きな配列では大幅に高速です。
-
JavaScriptで2つの二分探索木(BST)のノード値の合計が目標値に一致するか判定する方法
問題 JavaScriptの関数を作成します。この関数は、第1引数として1つ目の二分探索木のルートroot1を、第2引数として2つ目の二分探索木のルートroot2を受け取り、さらに第3引数として整数targetを受け取ります。 この関数は、「1つ目の木の中のあるノード」と「2つ目の木の中のあるノード」の値を足し合わせた結果がtargetと一致するようなペアが存在する場合にのみtrueを返し、存在しない場合はfalseを返す必要があります。 たとえば、次のような入力が与えられたとします。 const target = 23; 2つのBSTの例 この場合の出力は次のようになります。 const
-
【Python】K未満となる2数の和の最大値を求める方法
問題の概要整数の配列 A と整数 K が与えられたとき、i < j を満たす組み合わせの中で、A[i] + A[j] = S かつ S < K となるような最大の S を求めます。条件を満たす i と j のペアが存在しない場合は -1 を返します。たとえば、A = [34,23,1,24,75,33,54,8]、K = 60 の場合、34 と 24 を選ぶことで合計 58 が得られ、これは 60 未満です。他のどのペアよりも大きいため、出力は 58 となります。解法のアプローチこの問題は、すべてのペアを総当たりで確認するシンプルな手法で解くことができます。手順は以下の通りです。答