zoukankan      html  css  js  c++  java
  • [LeetCode] 206. Reverse Linked List(反转单链表)

    Description

    Reverse a singly linked list.

    反转一个单链表。

    Example

    Example 1

    Input: 1->2->3->4->5->NULL
    Output: 5->4->3->2->1->NULL
    

    Follow up

    A linked list can be reversed either iteratively or recursively. Could you implement both?

    你能以迭代/递归两种方式解答该问题吗?

    Solution

    反转单链表的迭代方法为大学数据结构课的基础内容,不再赘述,直接上代码:

    /**
     * Example:
     * var li = ListNode(5)
     * var v = li.`val`
     * Definition for singly-linked list.
     * class ListNode(var `val`: Int) {
     *     var next: ListNode? = null
     * }
     */
    class Solution {
        fun reverseList(head: ListNode?): ListNode? {
            var pre: ListNode? = null
            var mHead = head
    
            while (mHead != null) {
                val next = mHead.next
                mHead.next = pre
                pre = mHead
                mHead = next
            }
    
            return pre
        }
    }
    

    递归解法代码如下(来自于 discussion 的解法):

    /**
     * Example:
     * var li = ListNode(5)
     * var v = li.`val`
     * Definition for singly-linked list.
     * class ListNode(var `val`: Int) {
     *     var next: ListNode? = null
     * }
     */
    class Solution {
        fun reverseList(head: ListNode?): ListNode? {
            if (head?.next == null) {
                return head
            }
    
            // 先反转链表的其余部分
            val newHead = reverseList(head.next)
            // 将原链表的头插到反转后链表的尾
            // 因为上步操作完成后,head.next 实际上变成了新链表的尾节点,所以可以用以下方式将 head 插入进链表的尾部
            head.next?.next = head
            head.next = null
            // 返回新的头
            return newHead
        }
    }
    

    下面用两个例子来演示递归解法的过程:

    1. 假设有如下链表:

      A -> B

      首先,反转链表除头以外的剩余节点,这步操作后,链表结构不变,此时 newHead 指向 B

      A -> B

      head.next?.next = head 这步操作实际上把 B 的 next 指向了 A

      A <-> B

      最后把 A 的 next 指向 null,链表结构变成

      A <- B

      反转完成

    2. 假设有如下链表:

      A -> B -> C

      首先,反转链表除头以外的剩余节点,即反转 B -> C 这部分,按照情况 1,链表反转后的结果如下(newHead 指向 C)

      A -> B <- C

      head.next?.next 这步也是把 B 的 next 指向了 A

      A <-> B <- C

      最后把 Anext 置为 null,反转完成

      A <- B <- C

    最后,这题的递归解法比迭代解法快,我是想不通什么原因。

  • 相关阅读:
    iOS开发UI篇—使用storyboard创建导航控制器以及控制器的生命周期
    IOS开发UI篇—导航控制器属性和基本使用
    基于XMPP协议的aSmack源码分析
    XMPP-for-Android
    wecontact
    MyPhone
    Video conference server OpenMCU-ru
    WebRTC_Wrapper
    Sip-MCU
    WebRTC学习笔记
  • 原文地址:https://www.cnblogs.com/zhongju/p/13784022.html
Copyright © 2011-2022 走看看