• [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

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

  • 相关阅读:
    tornado用户指引(三)------tornado协程使用和原理(二)
    利用tornado使请求实现异步非阻塞
    在tornado中使用异步mysql操作
    Tornado 线程池应用
    Tornado异步与延迟任务
    tornado用户指引(二)------------tornado协程实现原理和使用(一)
    Tornado用户指引(一)-----------异步和非阻塞I/O
    Tornado异步之-协程与回调
    Python核心框架tornado的异步协程的2种方式
    c++ Map使用
  • 原文地址:https://www.cnblogs.com/zhongju/p/13784022.html
Copyright © 2020-2023  润新知