【题目描述】
反转一个单链表。
第一种做法 双指针
只需要改变next指针的指向就可以反转链表
定义两个指针一个pre,cur
pre 指向当前结点的前一个节点
cur 指向当前结点的后一个节点
每次让cur指针的next指向pre,实现一次反转
pre 和 cur 同时向前移动一个位置
最后 cur 指向 null 循环结束
返回 pre ,pre指向了新的头结点
这里的next指针相当于 cur
定义两个指针pre和next都指向null,然后就要开始反转了.
让cur节点指向下一个结点,将next指针的下一个结点指向pre。这个时候已经反转了第一个节点。接下来就是循环这个逻辑,继续移动pre和next节点.
最后next指针指向null,循环结束,链表也反转完成,这个时候我们return pre指针就可以了,pre指针指向了新的头结点。
class Solution {
public ListNode reverseList(ListNode head) {
//判断链表为空或链表的长度为1返回head
if(head == null || head.next == null) return head;
ListNode pre = null;//当前结点的前一个节点
ListNode cur = null;//当前结点的下一个节点
while( head != null){
cur = head.next;//记录当前结点的下一个位置
head.next = pre;//;当前结点指向pre
// pre 和 头结点 都移动一位往右走
pre = head;
head = cur;
}
return pre;
}
}
第二种做法 – 递归
递归的结束条件
节点为空或下一个结点为空
在函数内部,改变结点的指向,也就是head的下一个节点指向head 实现反转
遍历链表,现在递归到了第一个节点
第二个节点
第三个节点
这层返回的是3,拿到的是3,然后往回指,到节点2,head.next.next = head,2.next.next = 2,就等于 3.next = 2。往回指了,反转过来了,然后head.next = null 这个的作用是防止循环指向所以断开。
递归这个过程。
class Solution {
public ListNode reverseList(ListNode head) {
//递归终止条件是当前为空,或者下一个节点为空
if(head==null || head.next==null) {
return head;
}
//这里的cur就是最后一个节点
ListNode cur = reverseList(head.next);
//如果链表是 1->2->3,那么此时的cur就是3
//而head是2,head的下一个是3,下下一个是空
//所以head.next.next 就是3->2
head.next.next = head;
//防止链表循环,需要将head.next设置为空
head.next = null;
//每层递归函数都返回cur,也就是最后一个节点
return cur;
}
}
参考:
https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/