原题链接在这里:https://leetcode.com/problems/reverse-linked-list/
Method 1 和 Method 2 都是用的Iteration.
Method 1 是建一个dunmy,从前往后扫原链表,遇到一个就用改点的值建一个新的Node加在dunmy和dunmy.next之间。
Time O(n), Space O(n), 因为建了一个新的list.
Method 2 的好处就是更改原有链表,能不用extra space。思路就是逐个更改指针方向,这里建立很多变量,关系要搞清楚。head是最后的返回值,每一步更新head都更新成表头; tail是更改部分的尾部; temp是要断开连接前保存的原有head.next; pre 是记之前的head,所以更改关系顺序是就是
pre = head 保留当前head位置;
head = tail.next head移动到新的位置;
temp = head.next 保存下一步要更改的点;
head.next = pre 断开head.next 原有链接,指向pre;
tail.next = temp tail和下一步要更改的点连起来。
Time O(n), Space O(1).
AC Java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
/*Method 1
ListNode dunmy = new ListNode(0);
dunmy.next = null;
while(head!=null){
ListNode temp = dunmy.next;
ListNode nxt = new ListNode(head.val);
dunmy.next = nxt;
nxt.next = temp;
head = head.next;
}
return dunmy.next;
*/
//Method 2
if(head == null || head.next == null){
return head;
}
ListNode tail = head;
ListNode pre;;
ListNode temp;
while(tail.next != null){
pre = head;
head = tail.next;
temp = head.next;
head.next = pre;
tail.next = temp;
}
return head;
}
}
Method 3 是Recursion,reverseList(head.next)返回的是从head.next开始的reverse list,把head加在他的尾部即可。
他的尾部恰巧是之前的head.next, 这里用nxt表示。
Recursion 终止条件是head.next == null, 而不是head == null, head==null只是一种corner case而已。
AC Java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
//Method 3: Recursion
if(head == null){
return head;
}
if(head.next == null){
return head;
}
ListNode nxt = head.next;
ListNode res = reverseList(nxt);
head.next = null;
nxt.next = head;
return res;
}
}