在求职面试中,我被要求撤销一个链接列表。以下是我的解决方案:
public class E<T>{
private E<T> next;
private T val;
private E(T val) {
this.val = val;
}
public static <T> E<T> createNode(T val){
return new E<T>(val);
}
public E<T> add(E<T> next){
E<T> current = this;
while(current.next != null){
current = current.next;
}
current.next = next;
return this;
}
public E<T> reverse(){
if(this.next == null)
return this;
E<T> previous = new E<>(this.val); //<----- HERE
E<T> current = this.next;
while(current != null){
E<T> tmp = current.next;
this.val = current.val;
this.next = previous;
current.next = previous;
previous = current;
current = tmp;
}
return this;
}
}
但它确实看起来很难看。我无法理解如何处理的问题是我们最初只有this
引用,我们无法分配给任何东西(我们最后只有一个循环)。这就是我创建一个新节点的原因。但它看起来像一个可怕的解决方法。有没有“真正的方法”呢?
答案 0 :(得分:1)
如果你出于某种原因你不能使用像Collections.reverse这样的集合实用程序函数,就像Mena告诉你可以大致实现的那样:
public Iterable<T> Reverse<T>(Iterable<T> queue)
{
Stack<T> stack = new Stack<T>();
while(!queue.isEmpty())
stack.push(queue.pop());
return stack;
}
(*这是伪代码不是真正的实现)
public void Reverse<T>(Iterable<T> queue)
{
//todo: add null check
Stack<T> stack = new Stack<T>();
while(!queue.isEmpty())
stack.push(queue.pop());
while(!stack.isEmpty())
queue.append(stack.pop());
}
答案 1 :(得分:1)
嗯,这样做的一种方法是使用递归:
public E<T> reverse() {
if (this.next == null) return this;
E<T> node = this.next.reverse();
this.next.next = this;
this.next = null;
return node;
}
我测试了它,这很顺利,但如果列表太长,你可能会遇到麻烦:调用堆栈可能会爆炸。
迭代方式:
public E<T> reverse() {
E<T> previous = null;
E<T> current = this;
E<T> next = this.next;
while (next != null) {
current.next = previous;
previous = current;
current = next;
next = current.next;
}
current.next = previous; // We haven't reversed the last node yet.
return current;
}
同样,这已经过测试,并产生了预期的效果。
此外,可以改进add
方法,使其占用恒定时间:
public E<T> add(E<T> node) {
node.next = this;
return node;
}
答案 2 :(得分:1)
您将有权访问HEAD节点。因此,您可以从HEAD节点开始,只需更改链接的方向直到结束。最后,将HEAD-&gt; next设为null,将最后一个节点设为HEAD。
喜欢的东西。 (我还没有对它进行测试..只是在一些伪代码中写出这个想法)
cur = head.next;
prev = head;
while(cur)
{
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
head.next = null;
head = cur;
答案 3 :(得分:1)
这是一个解决问题的递归代码:
public E<T> reverse() {
if(next == null) return this;
else {
E<T> r = next.reverse();
this.next = null;
r.add(this);
return r;
}
}
这里是以迭代方式解决问题的代码:
public E<T> reverse() {
E<T> n = this;
E<T> last = null;
while(n.next != null) {
E<T> temp = n.next;
n.next = last;
last = n;
n = temp;
}
n.next = last;
return n;
}