目录
题目
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
思路
双指针法
改变指针next的指向就可以了
首先需要定义一个curr,用来指向头指针,反转之后头指针就变成尾指针了,尾指针会指向null,所以在头指针的前面我定义了一个pre,让他初始化等于null
然后我们在反转过程中只需要移动他们两个,让方向改变就可以了;但是此时curr指向了pre,我要移动他俩,后面那一个原本指向curr的箭头就没有了,无法进行移动。所以此时我们需要一个临时指针来存储,保存下来(把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。)
然后接着我们就可以开始移动了
一直移动一直移动直到最后curr指向null了,pre指向尾指针,此时就不用继续了,因为我们不需要让这个null空指针再指向头指针了。所以循环结束的条件是curr!=null(curr=null的时候不符合条件跳出循环)
代码
class Solution {//双指针
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode curr=head;
ListNode temp=null;
while(curr!=null){
temp=curr.next;//1
curr.next=pre;//2
pre=curr;//3
curr=temp;//4
}
return pre;
}
}
// 递归
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode prev, ListNode cur) {
if (cur == null) {
return prev;
}
ListNode temp = null;
temp = cur.next;// 先保存下一个节点
cur.next = prev;// 反转
// 更新prev、cur位置
// prev = cur;
// cur = temp;
return reverse(cur, temp);
}
}
// 从后向前递归
class Solution {
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
head.next = null;
return last;
}
}
细节
双指针法
1,2,3,4的顺序:
首先是在没赋值之前(箭头还连着的时候)让temp临时保存那个数值,所以他是第一步
此时curr的next就是指向了pre的位置,所以这是第二步
此时我们就改变完方向了,要让这两个指针向后移了
如果3,4互换位置的话,相当于curr先等于了它原来next的值,此时curr已经改变了,他改变以后才动pre,这是错误的。