Java の配列の内積:IntStream と整数の範囲
二つの配列の内積は、同じ添字の要素を掛けた値の合計です。先に要素を足したり、各配列の合計同士を掛けたりすると、別の計算になります。
この問題では、長さが等しい整数配列が与えられます。長さは 1–1,000、要素は -1,000 から 1,000 です。この範囲なら、結果は int に収まります。
処理の流れ
共通の添字ごとに要素の積を求め、その積を合計します。問題の制約では int に収まります。
添字ごとに積を求めて合計する
次の完全なクラスを Solution.java として保存します。Java 11 向けにコンパイル済みで、入力配列の長さが等しいことを前提としています。
import java.util.stream.IntStream;
public class Solution {
public int solution(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(i -> a[i] * b[i])
.sum();
}
}
IntStream.range(0, a.length) は終端の添字を含みません。各添字を a[i] * b[i] に変換し、sum() で積を合計します。プリミティブ型の添字ストリームなので、ボックス化した Integer のリストを作る必要はありません。
[1, 2, 3, 4] と [-3, -1, 0, 2] の場合、積は -3, -2, 0, 8 となり、結果は 3 です。負の符号は保持してください。絶対値を取ると内積が変わります。
int で十分な範囲
各積の絶対値は最大 1,000,000、項数は最大 1,000 です。したがって合計の絶対値は 1,000,000,000 以下で、Java の int の範囲内です。境界値の確認では、1,000 項での正負それぞれの最大の合計も対象としています。
入力の範囲が広がる場合、累積用の変数を long に変えるだけでは不十分なことがあります。(long) (a[i] * b[i]) は、int の乗算でオーバーフローした後に変換します。(long) a[i] * b[i] として乗算の前に型を拡張し、合計と戻り値の型も long に設計します。ここで提出するメソッドは、問題の int という契約を維持しています。
時間計算量は O(n)、追加領域は O(1) です。長さの不一致、null 配列、範囲外の要素を検証する汎用ベクトルライブラリではありません。
決められた英語の数字名を整数に変換する方法は、数字の単語と数値文字列を参照してください。
コメント