Да, вы можете исправить это, не используя дополнительное пространство.
Проблема заключается в выполнении этих двух строк одна за другой.
- itr1.remove ();
- itr2.hasNext ();
Вы можете использовать два итератора для одного и того же списка одновременно. Если вы осторожны .
Но как только один из этих итераторов изменил список (как это происходит с itr1.remove()
), вы больше не можете использовать другой итератор (поэтому вы не можете вызвать itr2.hasNext()
).
Решение состоит в том, чтобы поставить break
после itr1.remove()
. И обновить count1
:
public static void RemoveWithoutBuffer(LinkedList l) {
ListIterator itr1 = l.listIterator();
int count1 = 0;
int count2 = 0;
while (itr1.hasNext()) {
Object next = itr1.next();
count1++;
count2 = 0;
ListIterator itr2 = l.listIterator();
while (itr2.hasNext()) {
count2++;
if (count2 == count1)
break;
if (itr2.next() == next){
itr1.remove();
--count1;
break;
}
}
}
}
Более элегантным решением было бы сравнение элементов после текущего, а не элементов перед текущим:
public static void RemoveWithoutBuffer(LinkedList l) {
ListIterator itr1 = l.listIterator();
while (itr1.hasNext()) {
Object next = itr1.next();
ListIterator itr2 = l.listIterator( itr1.nextIndex() );
while (itr2.hasNext()) {
if (itr2.next() == next) {
itr1.remove();
break;
}
}
}
}
Это не лучшие решения с точки зрения вычислительной сложности. Если пространство памяти не является проблемой, решение с использованием хэш-набора является лучшим в отношении сложности вычислений.
Но речь идет о параллельной обработке через итераторы, а не об оптимизации сложности.