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

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

1. 题目信息

题目分析:

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

2. 指针

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

AC代码:

  1. /** * 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; } * } */
  2. class Solution {
  3. public ListNode reverseList(ListNode head) {
  4. // 就是非递归的链表反转模板
  5. ListNode pre = null, cur = head;
  6. while(cur != null){
  7. ListNode after = cur.next;
  8. cur.next = pre;
  9. pre = cur;
  10. cur = after;
  11. }
  12. return pre;
  13. }
  14. }

解题思路:

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

此时的prenull

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

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

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

3. 递归

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

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

AC代码

  1. /** * 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; } * } */
  2. class Solution {
  3. public ListNode reverseList(ListNode head) {
  4. if(head == null || head.next == null){
  5. return head;
  6. }
  7. ListNode cur = reverseList(head.next);
  8. head.next.next = head;
  9. head.next = null;
  10. return cur;
  11. }
  12. }

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

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

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

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

相关文章