我正在尝试使用堆栈迭代地反转链表。我已经确定了问题发生的地方,但是对于我的生活,我无法弄清楚当我调用ListNode的下一个方法时代码没有正确迭代的原因。我在下面的代码中标记了错误发生的地方。
这是我运行代码时的结果:
Before: 1->2->3->4->null
After: 4->3->3->4->null
这就是结果:
Before: 1->2->3->4->null
After: 4->3->2->1->null
有人能指出我正确的方向吗?谢谢!
以下是代码:
public class Solution {
public static void main(String[] args) {
private static Solution soln = new Solution();
ListNode head = makeLinkedList(4);
System.out.print("Before: ");
printLinkedList(head);
System.out.println();
soln.reverseList(head);
System.out.print(" After: ");
printLinkedList(head);
System.exit(0);
}
public ListNode reverseList(ListNode head) {
Stack<ListNode> listContents = new Stack<ListNode>();
// iterate list and add to stack
ListNode tmp = head;
while (tmp != null) {
listContents.push(tmp);
tmp = tmp.next;
}
// iterate list again and replace each val with stack val
tmp = head;
while (tmp != null) {
tmp.val = listContents.pop().val;
// this is where the code seems to fail
tmp = tmp.next;
}
return head;
}
}
如何定义ListNode:
public class ListNode {
int val;
ListNode next = null;
public ListNode(int item) {
val = item;
}
}
以下是我创建链接列表的方法:
private static ListNode makeLinkedList(int numNodes) {
ListNode head = null;
ListNode tmp = null;
for (int i = 1; i < numNodes + 1; i++) {
if (tmp == null) {
tmp = new ListNode(i);
head = tmp;
} else {
tmp.next = new ListNode(i);
tmp = tmp.next;
}
}
return head;
}
辅助方法:
private static void printLinkedList(ListNode head) {
ListNode tmp = head;
while (tmp != null) {
System.out.print(tmp.val + "->");
tmp = tmp.next;
}
System.out.print("null");
}
答案 0 :(得分:3)
问题是您将ListNode
存储在Stack
而不仅仅是值中。这样,您将覆盖您正在阅读的节点的值:
修复它的几种可能方法:
ListNode
。Stack
的情况下完成 - 请参阅@xenteros的回答。答案 1 :(得分:2)
如果可能,应通过撤消链接来撤消链接列表。我尝试以下方法:
public static ListNode reverseList(ListNode head) {
// iterate list and add to stack
ListNode current = head;
ListNode previous = null;
ListNode temp = null;
while (current.next != null) {
temp = previous;
previous = current;
current = current.next;
previous.next = temp;
}
current.next = previous;
return current;
}
它返回一个新头。用法示例:
public static void main(String[] args) {
ListNode head = makeLinkedList(4);
System.out.print("Before: ");
printLinkedList(head);
System.out.println();
head = reverseList(head);
System.out.print(" After: ");
printLinkedList(head);
System.exit(0);
}
>>Before: 1->2->3->4->null
>>After: 4->3->2->1->null
>>Process finished with exit code 0
算法描述如下: 对于列表中的每个节点,不是链接下一个元素,而是链接前一个元素并将最后一个元素作为头部返回。
答案 2 :(得分:1)
这种情况正在发生,因为您在不知道它的情况下改变了LinkedList。换句话说,当你在LinkedList中覆盖任何更多的值时,你之前在堆栈上推送的节点也会被修改。因此,确保不会发生这种情况的一种方法是在堆栈上实例化并推送新节点(副本):
public ListNode reverseList(ListNode head) {
Stack<ListNode> listContents = new Stack<ListNode>();
// iterate list and add to stack
ListNode tmp = head;
while (tmp != null) {
ListNode newNode = new ListNode(temp);
listContents.push(newNode);
tmp = tmp.next;
}
// iterate list again and replace each val with stack val
tmp = head;
while (tmp != null) {
tmp.val = listContents.pop().val;
tmp = tmp.next;
}
return head;
}
对ListNode
类进行简单修改以添加复制构造函数:
public class ListNode {
int val;
ListNode next = null;
public ListNode (ListNode that){
this.val = that.val;
this.next = null; //Could be that.next
}
public ListNode(int item) {
val = item;
}
}