文章目录
题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
思路
如图,反转链表不需要重新定义一个链表浪费空间,只需要通过指针完成反转,我们可以想到从前往后和从后往前两种方式,那么从前往后双指针由图·可知,我们需定义一个cur指针用于循环条件,用一个pre指针,实现指针反转,还需一个temp指针,暂时保存下一个节点,一般我们在处理一个有用节点本身值有用但要被赋值时,均会想到先将他本身值赋给另一个变量,在自己被赋值。所以,我们在while循环,先将cur.next赋值给temp,在将pre赋值给cur.next,在将cur值赋值给pre,最后再将temp值赋给cur.递归底层逻辑一样,不断将cur指向pre,注意递归终止条件:cur == null
从前向后
双指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
ListNode temp = null;
while(cur!=null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
递归
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
private ListNode reverse(ListNode pre,ListNode cur){
if(cur == null){
return pre;
}
ListNode temp = null;
temp = cur.next;
cur.next = pre;
return reverse(cur,temp);
}
}
从后向前递归
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null)return null;
if(head.next == null)return head;
ListNode last = reverseList(head.next);
head.next.next = head;
head.next = null;
return last;
}
}