Leetcode 206. 反转单链表

Leetcode 206. 反转单链表

一、题目描述

难度: easy 标签:链表

反转一个单链表。

示例:

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

进阶:

能否使用迭代和递归两种方式来解决这道题?

二、自己的解法

链表的题目大多没有太难的技巧,非常容易理解,只是比较考察编程能力。特别需要注意链表的指针,在解决这类问题是特别容易犯迷糊。解题时,自己在草稿纸上画图,帮助理解,能够更加形象的理解这类题目。下面是我的解法:

private static ListNode reverseList(ListNode head) {
    ListNode prev = null;

    while (head != null){
        ListNode next = head.next;
        head.next = prev;
        prev = head;
        head = next;
    }

    return prev;
}

复杂度分析: 只借助常量时间的空间,因此空间复杂度是 O(1),整个过程只遍历了一次链表,因此时间复杂度是 O(n)。

运行结果: 时间击败 100%,空间击败 98%,是一个非常不错的解法。

三、官方题解

1. 迭代法

和上面提到的我的思路是一样的,只是代码实现略有不同,可以参考一下:

public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

复杂度上面已经分析过了,不再赘述。

2. 递归法

这种思路稍微巧妙一点,需要多花点时间理解,可以借助迭代的写法来思考如果写成递归代码,官方参考如下:

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) return head;
    ListNode p = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return p;
}

下面是我写的递归的代码,和官方题解相比稍微有些冗余,不够简洁,但还是贴出来供大家参考:

private static ListNode reverseList2(ListNode head) {
    if(head == null){
         return head;
    }
    return helper(null, head, head.next);
}

private static ListNode helper(ListNode prev, ListNode head, ListNode next) {
    ListNode back = head.next;
    head.next = prev;
    if (next == null){
        return head;
    }
    return helper(head, back, back.next);
}

复杂度分析: 整个过程还是只遍历一次链表,因此时间复杂度是 O(n),由于使用了递归,在函数调用的过程当中,会产生中间变量,因此空间复杂度是 O(n)。

运行结果: 时间击败 100%,空间击败 98%。

发布了55 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Rose_DuanM/article/details/103173436
今日推荐