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

文章目录

    • 1. 题目信息
    • 2. 指针
    • 3. 递归

1. 题目信息

递归和指针 -- 带你拿捏链表反转_第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. 刚开始的时候如下图所示

递归和指针 -- 带你拿捏链表反转_第2张图片
此时的prenull

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

递归和指针 -- 带你拿捏链表反转_第3张图片

  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;
    }
   
}

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

递归和指针 -- 带你拿捏链表反转_第4张图片

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

递归和指针 -- 带你拿捏链表反转_第5张图片

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

递归和指针 -- 带你拿捏链表反转_第6张图片
递归和指针 -- 带你拿捏链表反转_第7张图片

有的同学可能会问为什么最后返回的是正确的结果呢(为什么是5所在的结点呢)?

你有没有发现我们一直返回的是cur,所以就是到倒数第二个结点时(也就是递归返回时的cur),那么也就是5所在的结点

你可能感兴趣的:(LeetCode,算法与数据结构,链表,leetcode,数据结构)