递归和指针 -- 带你拿捏链表反转

x33g5p2x  于2021-11-21 转载在 其他  
字(1.2k)|赞(0)|评价(0)|浏览(358)

1. 题目信息

题目分析:

给定一个链表,题目要求返回反转链表后的头节点。例如1 -> 2 -> 3 -> 4 -> 5,反转后的结果5 -> 4 -> 3 -> 2 -> 1

2. 指针

所使用到的指针:pre : 前一个结点cur : 当前结点after : cur后面一个结点

AC代码:

/** * 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 pre = null, cur = head;

        while(cur != null){
            ListNode after = cur.next;
            cur.next = pre;
            pre = cur;
            cur = after;
        }

        return pre;
    }
    
}

解题思路:

  1. 刚开始的时候如下图所示

此时的prenull

  1. 经过一次执行代码之后如下图所示

  1. 依次类推就可以彻底的反转链表了。

特别注意点
after 必须要在循环内部才能进行赋值,为的就是后面的反转操作都相同进而使用while

3. 递归

为什么可以使用到递归求解呢?

因为反转链表无非就是将当前结点的下一个结点指向自己,然后自己的next指针指向null。所以都是一系列的重复操作,所以可以使用递归

AC代码

/** * 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 || head.next == null){
            return head;
        }

        ListNode cur = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return cur;
    }
   
}

当递归到最后的一个结点返回如下图所示

当前head4所在的结点head.next = null

继续返回,当前head 为 3 所在的结点

有的同学可能会问为什么最后返回的是正确的结果呢(为什么是5所在的结点呢)?
你有没有发现我们一直返回的是cur,所以就是到倒数第二个结点时(也就是递归返回时的cur),那么也就是5所在的结点

相关文章