← Заметки

Последовательность с шагом x в Java: расширение типа до умножения

n значений, начиная с x, — это от x × 1 до x × n. Результаты могут выходить за диапазон int, поэтому long нужен и для результирующего массива, и для самого умножения.

Условие задачи ограничивает x диапазоном от -10 000 000 до 10 000 000, а n — от 1 до 1 000. Модуль последнего значения может достигать 10 000 000 000, поэтому нужен массив long.

Ход обработки

Преобразуем индексы с нуля в номера членов, расширяем x до 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 связывает вычисления над массивами со строками и коллекциями.

Обсуждение

Посмотреть на GitHub ↗