← 開発ノート

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 コーディング問題ガイドにまとめています。

コメント

GitHubで見る ↗