Сравнение списка методом For-Each
Нужно реализовать функцию, которая из элементов переданного списка целых чисел (List) составит новый список (List), состоящий из всех элементов списка за исключением локальных минимумов. Будем считать что локальным минимумом - элемент соседи которого (элемент справа и слева; только справа для - [0]го элемента; только слева - для последнего элемента списка) строго больше заданного элемента. Не обращаться к спискам по индексам, перебирать элементы только с помощью цикла For-Each
for (int value: list){...}
Пример: { 1, 2, 3, 5, -1, 0, 5, 3 } -> { 2, 3, 5, 0, 5}
У меня самого получилось реализовать только с помощью обычного цикла for и обращаясь к элементам по индексам
public static void process(List<Integer> list) {
List<Integer> listFinal = new ArrayList<>();
for (int value = 0; value < list.size(); value++) {
if (value == 0 && list.get(value + 1) < list.get(value)) {
listFinal.add(list.get(value));
}
if (value > 0 && value < list.size() - 1) {
if (list.get(value + 1) < list.get(value) || list.get(value - 1) < list.get(value)) {
listFinal.add(list.get(value));
}
}
if (value == list.size() - 1 && list.get(value) > list.get(value - 1)) {
listFinal.add(list.get(value));
}
}
System.out.println(listFinal);
}
Ответы (2 шт):
Можно завести 3 переменные a,b,c, которые будут последовательно заполняться числами из списка в цикле. Проверяем их и добавляем в итоговый список те числа, которые НЕ локальные минимумы. Особенности сравнения у первого и последнего числа.
Также вводим переменную iter, которая нужна, чтобы обеспечить первоначальную "загрузку" первых двух чисел из списка в переменные.
public class Main {
public static void process(List<Integer> list) {
List<Integer> listFinal = new ArrayList<>();
int a, b = Integer.MIN_VALUE, c = Integer.MIN_VALUE, iter = 0;
for (int n : list
) {
a = b;
b = c;
c = n;
if (iter < 2) {
if (!(b < c)) listFinal.add(b);
iter++;
} else {
if (!(b < a & b < c)) listFinal.add(b);
}
}
if (!(c < b)) listFinal.add(c);
System.out.println(listFinal);
}
public static void main(String[] args) {
process(Arrays.asList(1, 2, 3, 5, -1, 0, 5, 3));
}
}
[2, 3, 5, 0, 5]
Можно использовать очередь ограниченного размера, в которой будут размещаться элементы исходного списка. По мере прохождения по исходному списку, размер очереди будет поддерживаться не более 2 элементов.
Также по условию задачи метод process должен вернуть новый список без локальных минимумов:
public static List<Integer> process(List<Integer> list) {
List<Integer> result = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
for (Integer n : list) {
boolean empty = queue.isEmpty();
queue.offer(n);
if (!empty) {
if (queue.size() < 3) {
Integer prev = queue.peek();
if (prev >= n) {
result.add(prev);
}
} else { // queue size should be 3 here
Integer first = queue.poll();
Integer prev = queue.peek();
if (!(prev < first && prev < n)) {
result.add(prev);
}
}
}
}
if (queue.size() == 2) {
Integer first = queue.poll();
Integer prev = queue.peek();
if (prev >= first) {
result.add(prev);
}
} else if (!queue.isEmpty()) {
result.add(queue.poll());
}
return result;
}
Тест:
List<List<Integer>> data = Arrays.asList(
Arrays.asList(),
Arrays.asList(22),
Arrays.asList(1, 2),
Arrays.asList(3, 2),
Arrays.asList(1, 2, 3, 5, -1, 0, 5, 3)
);
for (List<Integer> list : data) {
System.out.println(list + " => " + process(list));
}
[] => []
[22] => [22]
[1, 2] => [2]
[3, 2] => [3]
[1, 2, 3, 5, -1, 0, 5, 3] => [2, 3, 5, 0, 5]