Java の IntStream で符号付きの値を合計する
絶対値と符号が別々に与えられた場合は、対応する添字で符号を適用してから合計します。signs[i] は true なら正、false なら負を意味するため、一つの条件式で各値を復元できます。
この問題では、配列の長さが等しく 1 から 1,000、絶対値が 1 から 1,000 であることが保証されています。符号だけを並べ替えると元の値との対応が崩れるため、配列は与えられた順序で処理します。
処理の流れ
両配列の同じ添字を読み、符号を適用してから、符号付きの値を合計します。
対応する添字を一緒に読む
次の完全なクラスを Solution.java として保存します。Java 11 向けにコンパイルし、JDK 17 で実行済みです。
import java.util.stream.IntStream;
public class Solution {
public int solution(int[] absolutes, boolean[] signs) {
return IntStream.range(0, absolutes.length)
.map(i -> signs[i] ? absolutes[i] : -absolutes[i])
.sum();
}
}
IntStream.range は添字 0 を含み、absolutes.length を含みません。map で各絶対値に符号を適用し、sum でその結果を足します。このメソッドは入力を変更せず、符号付きの値を格納する別の配列も作りません。
| 絶対値 | 符号 | 実際の値 |
|---|---|---|
| 4 | true | 4 |
| 7 | false | -7 |
| 12 | true | 12 |
これらの合計は 9 です。入力が [1,2,3] と [false,false,true] なら、相殺されて 0 になります。正と負のフラグの数を数えるだけでは不十分です。各項の絶対値も関係します。
整数の範囲と契約
項数は最大 1,000、各項の絶対値は最大 1,000 なので、合計の絶対値は 1,000,000 以下です。すべて正、またはすべて負の境界値も int に収まります。時間計算量は O(n)、追加領域は O(1) です。
このメソッドは、問題に従った有効な絶対値と同じ長さを前提としています。任意のアプリケーション入力に必要な null、長さ、値の検証を代替するものではありません。範囲が広がる場合は、項と累積用の変数の両方について型を再検討する必要があります。
別の二つの配列の計算として配列の内積を、int を超える結果についてはlong を使った x 間隔の数列を参照してください。学習の順序は Java コーディング問題ガイドにまとめています。
コメント