如讨论所述,在一般情况下这是不可行的,您需要对单个操作的复杂性做出一些假设。如果您的迭代器具有常数时间的next()
和previous()
,请使用已经给出的解决方案。它应该适用于LinkedList和ArrayList。
我考虑了一个适用于单向链表的解决方案(但不适用于类似ArrayList的东西),但遗憾的是ListIterators add
方法在光标之前而不是之后插入元素,因此不能使用List + ListIterator接口(如果我们无法修补ListIterator实现以缓存预插入元素以允许在O(1)中进行单个previous()
之后的add
)。
在这里,假设有一个简单的带有下一个指针的Node
类:
void reverseList(Node first, Node last) {
while(first != last) {
Node temp = first;
first = temp.next;
temp.next = last.next;
last.next = temp;
}
}
从索引术语来看,这将是类似于这样的内容:
public void reverseList(List<T> list) {
int index = list.size() -1;
while(n > 0) {
T element = list.remove(0);
list.add(n, element);
n--;
}
}
在ListIterator术语中,这将类似于这样:
public void reverseList(List<T> list) {
ListIterator<T> it = list.listIterator(list.size());
while(it.previousIndex() > 0) {
T element = list.remove(0);
it.add(element);
it.previous();
}
}
当然,通常的单向链表实现不会有O(1)的previous
实现,因此在那里它将无法工作,如前所述。(并且它们可能会抛出ConcurrentModificationException异常,或返回错误的previousIndex
。)
List<T>
;这样做并不能让你对类型进行约束(例如,你不能假设索引是O(n)或其他),甚至可能根本无法修改列表。 :-) - Donal FellowsList
,索引“可以”是线性时间。因此它可能会更快,但我认为我们应该通过省略推断它不可能更慢,因此它是O(n)。 - Steve Jessop