一、题目描述:
给你单链表的头节点 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 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/reverse-linked-list 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
这道题考察了什么思想?你的思路是什么?
我的第一思路很简单,从链表头开始,把第一节点和第二节点倒转,然后保留第二节点的位置,继续将第二节点和第三节点进行倒转,直到最后一个节点完成倒转,然后返回链表头即可。
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
但是我的思路存在问题,就是我的原头节点还是指向第二个节点,这就导致节点遍历时会陷入无尽的深渊,直到永远。。。
于是经过思考,我们需要保留前置节点,而初始前置节点为nil,这就导致原头节点会指向为nil的前置节点,这样最终也不会出现死循环。
需要注意反转操作过程中不能丢失节点数据!
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return newHead
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
curr := head
for curr != nil {
next := curr.Next
curr.Next = prev
prev = curr
curr = next
}
return prev
}
四、总结:
迭代方法时间复杂度为O(n),空间复杂度为O(1),而递归方法空间复杂度和时间复杂度都为o(n)。