Loading

[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

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

posted @ 2020-10-09 09:06  Zhongju.copy()  阅读(79)  评论(0编辑  收藏  举报