206. 反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
Stack<ListNode> list = new Stack();
while(head!=null){
list.push(head);
head = head.next;
}
int flag = 1;
ListNode head2 = null;
while(!list.empty()){
ListNode nhead = list.pop();
nhead.next = null;
if(flag == 1){
head = nhead;
head2 = head;
flag = 0;
}else{
head.next = nhead;
head = head.next;
}
}
return head2;
}
}
2.官方解法之迭代
方法一:迭代
假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。
在遍历列表时,将当前节点的 next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用!
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
方法二:递归
递归版本稍微复杂一些,其关键在于反向工作。假设列表的其余部分已经被反转,现在我该如何反转它前面的部分?
假设列表为:
n1→…→nk−1→nk→nk+1→…→nm→∅
若从节点 n{k+1}nk+1 到 n{m}nm 已经被反转,而我们正处于 n_{k}n**k。
n1→…→nk−1→nk→nk+1←…←nm
我们希望 n{k+1}nk+1 的下一个节点指向 n{k}nk。
所以,n{k}nk.next.next = n{k}nk。
要小心的是 n_{1}n1 的下一个必须指向 Ø 。如果你忽略了这一点,你的链表中可能会产生循环。如果使用大小为 2 的链表测试代码,则可能会捕获此错误。
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode p = reverseList(head.next);
head.next.next = head;
head.next = null;
return p;
}