Вот код для удаления только одного из максимальных значений (в данном случае первого, но это не имеет значения) из списка. Это O(n)
во времени и O(n)
в пространстве (за пределами ввода).
public List<Integer> removeOneOfTheMax(List<Integer> nums) {
int max = Integer.MIN_VALUE;
int maxIndex = -1;
Iterator<Integer> it = nums.iterator();
for (int i = 0; it.hasNext(); i++) {
Integer temp = it.next();
if (max < temp) {
maxIndex = i;
max = temp;
}
}
nums.remove(maxIndex);
return nums;
}
1.. Что было бы эквивалентно методу, использующему API потока Java 8? Я хотел бы сохранить сложность времени и пространства, поэтому сортировка не разрешена.
2. На самом деле, если вы передадите LinkedList
в код выше, сложность пространства будет O(C)
(опять же, вне ввода), но насколько я понимаю .stream()
создает дополнительную структуру данных, поэтому эквивалент потока API должен быть не менее O(n)
в пространстве. Исправьте меня, если я ошибаюсь.
Потоковое решение может выглядеть так:
int maxIndex = IntStream.range(1, nums.size()).reduce(0, (i, j) -> {
int left = nums.get(i);
int right = nums.get(j);
return Integer.max(left, right) == left ? i : j;
});
nums.remove(maxIndex);
Под ним будет Spliterator
.
Сама операция потока не собирается создавать дополнительные структуры данных.
(i, j) -> nums.get(i)>=nums.get(j)? i : j
O(n)
в космосе»? Поскольку уже существующийList
не учитывается, требования к памяти, масштабируемые в зависимости от размера списка, отсутствуют. ЭтоO(1)
в пространстве, независимо от того, используете ли выArrayList
илиLinkedList
. Это было бы иначе при использованииCopyOnWriteArrayList
, но это не было бы ответственностью алгоритма.