题目描述
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
解析
解法一:堆栈(迭代&递归)
- 思路:第一思路便是利用堆栈,将链表节点依次入栈,再出栈。
public ListNode reverseList(ListNode head) {
if(head==null) return null;
Deque<ListNode> stack = new LinkedList<>();
while(head.next!=null) {
stack.push(head);
head=head.next;
}
ListNode iterNode=head;
while(!stack.isEmpty()) {
iterNode.next=stack.pop();
iterNode=iterNode.next;
}
iterNode.next=null;
return head;
}
- 时间复杂度是O(N),空间复杂度是O(N)
- 以上是迭代的方法,同样利用堆栈,用递归思想解决,运行时间上快一些。代码如下:
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null) return head;
ListNode node = reverseList(head.next);
head.next.next=head;
head.next=null;
return node;
}
解法二:双指针
- 思路:要将链表反转,需要遍历链表节点,并将该节点的前驱节点改为其后继节点,然而链表节点并没有指向前驱节点的指针,所以需要一个节点指向其前驱节点;而节点的原后继节点同样需要遍历,但当改原节点的前驱为后继之后,原后继节点已经与当前节点失去了联系,所以需要一个节点在改“路”之前就把后继节点保存下来。代码如下:
public ListNode reverseList(ListNode head) {
ListNode preNode=null, iterNode=head;
while(iterNode!=null) {
ListNode nextNode = iterNode.next;
iterNode.next=preNode;
if(nextNode!=null) {
preNode=iterNode;
iterNode=nextNode;
nextNode=nextNode.next;
}else break;
}
return iterNode;
}