【算法】反转链表

97 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

题目

给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点。

解题思路

关键词:链表;翻转;头节点

关键信息:递归;遍历

指针解法

遍历链表倒序解法方法是将当前节点next指向前一个节点,因为链表特点next节点无法直接获取到前一个节点,需要暂存一个节点在之后赋值。

  1. 初始化先获取到首节点和第二个节点。首节点先指向空节点。
  2. 对next节点循环,next的下一个节点指向header节点;header赋值为next节点(相当于next下一个节点指向了next)
  3. old节点变成next下一个进入循环的头。整个过程节点(1,2,,3) -> (2,1,3)
    public ListNode reverseList(ListNode head) {
             if(head == null) return null;
            if(head.next == null) return head;
            ListNode header = head;
            ListNode next = head.next;
            header.next = null; //首个指向 null
            // 节点第二个指向前一个值
            while(next != null){
                ListNode old = next.next; //  old = 3
                next.next = header; // 2 -> 1
                header = next;  // header = 2
                next = old; // next = 3
            }
            return header;
    }

另外一种更清晰解法同样也是遍历节点。

  1. 第三个节点变成第一个节点。
  2. 第二个节点变成头部节点(第一个节点)。
  3. 第三个节点变成第二个节点。
  4. 下一次循环就是第二个节点。(原先是第三个
  5. 依次如上循环不断交换次序遍历链表。
 public ListNode reverseList(ListNode head) {
            if(head == null) return null;
            ListNode newHead = head;
            while(head.next != null){
               ListNode next = head.next.next;
               head.next.next = newHead;
               newHead = head.next;
               head.next = next;
            }
            return newHead;
 }

递归解法

链表解法必有递归!和遍历解法思路相同:下一个节点需要指向上一个节点。

  1. 根据递归原理先判断终结条件
  2. 执行递归方法(下一个节点变成头节点
  3. 实现递归逻辑(头节点变成第三个节点;第三个节点变第二个节点
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }

递归方法理解确实有点难以消化;使用递归解法还是需要大量练习和深入理解才行。

参考