Java で x 間隔の数列を生成する:乗算前の型拡張
x から始まる n 個の値は、x × 1 から x × n までです。結果が int の範囲を超えることがあるため、結果の配列と乗算そのものの両方に long を使う必要があります。
問題では、x は -10,000,000 から 10,000,000、n は 1 から 1,000 です。最後の値の絶対値は 10,000,000,000 に達することがあるため、long の配列が必要です。
処理の流れ
ゼロ始まりの添字を項番号に変え、乗算前に x を long に拡張してから順番に集めます。
添字を項番号に変換する
完全なクラスを Solution.java として保存します。原文のコードは Java 11 向けにコンパイルされ、JDK 17 で実行されています。
import java.util.stream.IntStream;
public class Solution {
public long[] solution(int x, int n) {
return IntStream.range(0, n)
.mapToLong(i -> (long) x * (i + 1))
.toArray();
}
}
IntStream.range(0, n) は 0 から n-1 までの添字を生成します。i + 1 を掛けることで最初の値が x、最後が x×n になります。x×0 から始めると、求められる数列が変わってしまいます。
| x | n | 結果 |
|---|---|---|
| 2 | 5 | [2,4,6,8,10] |
| -4 | 2 | [-4,-8] |
| 0 | 3 | [0,0,0] |
x が負なら値は減少し、x=0 ならすべてゼロになります。項の順番を保ってください。これはソートの問題ではありません。
mapToLong だけでは積を保護できない
mapToLong の中でも、先に x * (i + 1) を評価すると、両オペランドが int なので int の乗算になります。(long) (x * (i + 1)) も、オーバーフローが起きた後の型変換です。
この例では (long) x * (i + 1) により、先にオペランドの型を拡張します。原文の検証では、正負の境界について、それぞれ 10,000,000,000 と -10,000,000,000 で終わる参照配列全体を比較しています。より小さい正・負・ゼロの入力も、加算の繰り返しで作った配列と比較しています。
時間計算量は O(n)、戻り値の配列を含む空間計算量は O(n) です。問題の入力条件に従う実装であり、数列の長さや任意の API 入力を汎用的に検証するものではありません。
条件内で int に収まる計算は、符号付きの合計と配列の内積を比較してください。Java コーディング演習ガイドでは、配列の計算から文字列・コレクションへと学べます。
コメント