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%。