剑指 Offer 24. 反转链表

607 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 15 天,点击查看活动详情

本文已同步至:村雨遥

题目

剑指 Offer 24. 反转链表

描述

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL

输出: 5->4->3->2->1->NULL  

限制:

0 <= 节点个数 <= 5000

实现方法

方法 1:递归

思路

  • 首先是找到递归的终止条件,也就是当前节点指向 NULL 时。
  • 利用递归,从头节点一直递归到链表的尾节点,该结点即为反转后的头节点。
  • 然后每递归一次就修改当前节点 current 所指向的节点引用。
  • 最后返回的结果即为反转后的链表。

实现

class Solution {
    public ListNode reverseList(ListNode head) {
        return recursive(head, null); 
    }
    private ListNode recursive(ListNode current, ListNode pre) {
        // 递归终止条件
        if (current == null){
            return pre;
        }
        // 递归当前节点的后继节点
        ListNode res = recursive(current.next, current);  
        // 然后修改节点引用的指向
        current.next = pre;
        return res;                  
    }
}

结果

方法 2:双指针

思路

链表反转之后,原链表的头节点即为反转后的尾节点。假设头节点为 head,然后定义一个指针 current 用于指向当前节点并初始化为头节点 head。然后每次都让都头节点 head 的后继节点的 next 指向当前节点 current,从而实现一次局部反转。完成上述反转之后,将当前节点 current 和头节点 headnext 同时向前移动一个位置,直到当前节点 current 到达链表的尾节点。

实现

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null){
            return null;
        }
        
        ListNode current = head;

        while(head.next != null) {
            ListNode tmp = head.next.next;
            head.next.next = current;
            current = head.next;
            head.next = tmp;
        }
        return current;
    }
}

结果