leetcode 206题,反转链表
Posted Demonwuwen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 206题,反转链表相关的知识,希望对你有一定的参考价值。
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
题解
一 、递归
因为是单链表,可以不难想到用递归深入到最后一个节点,再逐层返回。这种方法有一丢丢难以理解。
尤其是为啥要
head.Next.Next = head
head.Next = nil
其关键在于反向工作。假设
链表为:
n
1
→
…
→
n
k
−
1
→
n
k
→
n
k
+
1
→
…
→
n
m
→
∅
n1→…→nk−1→nk →nk+1 →…→nm→∅
n1→…→nk−1→nk→nk+1→…→nm→∅
当我们的递归返回到第nk节点处,nk后面的部分均已经被反转,
现在的状态:
n
1
→
…
→
n
k
−
1
→
n
k
→
n
k
+
1
←
…
←
n
m
n1→…→nk−1→nk →nk+1 ←…←nm
n1→…→nk−1→nk→nk+1←…←nm
此时,我们需要将nk+1的下一个节点指向nk。
n
k
.
n
e
x
t
.
n
e
x
t
=
n
k
nk.next.next = nk
nk.next.next=nk
此时链表状态:
n
1
→
…
→
n
k
−
1
→
n
k
←
n
k
+
1
←
…
←
n
m
n1→…→nk−1→nk ←nk+1 ←…←nm
n1→…→nk−1→nk←nk+1←…←nm。
此时,应把
n
k
.
n
e
x
t
nk.next
nk.next置为空,否则当链表只有两个节点时,就成了一个循环链表了。
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil{
return head
}
P := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return P
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),假设 n n n是列表的长度,那么时间复杂度为 O ( n ) O(n) O(n)。
- 空间复杂度: O ( n ) O(n) O(n),由于使用递归,将会使用隐式栈空间。递归深度可能会达到 n n n层
二 、迭代
在遍历列表时,将当前节点的 n e x t next next指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
current := head
var prev *ListNode = nil
for current != nil {
temp := current.Next
current.Next = prev
prev = current
current =temp
}
return prev
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),假设 n n n 是列表的长度,时间复杂度是 O ( n ) O(n) O(n)。
- 空间复杂度: O ( 1 ) O(1) O(1)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list
以上是关于leetcode 206题,反转链表的主要内容,如果未能解决你的问题,请参考以下文章
精选力扣500题 第1题 LeetCode 206. 反转链表 c++详细题解