剑指 Offer 24. 反转链表
Posted 炫云云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 24. 反转链表相关的知识,希望对你有一定的参考价值。
剑指 Offer 24. 反转链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
[外链图片转存中…(img-uMVTtihw-1630078203160)]
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
[外链图片转存中…(img-fEg773hU-1630078203162)]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
递归逆序
思路:
1、首先将1 -> 2 -> 3 ->4变成1 -> 4-> 3 -> 2(其中2 -> 3 ->4变成4-> 3 -> 2,采用递归方式实现)
2、再将head头节点1移到尾巴,作为尾结点,由于上一个尾结点2,是原先的head.next,此时将2的next指针指向头节点,即head.next.next = head,然后尾结点指向空,即head.next = None
[外链图片转存中…(img-eJ1LkIEX-1630078203163)]
3、特殊情况:头节点为空或者只有1个节点
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
#如果链表为空或者链表中只有一个元素
if head is None or head.next is None:
return head
else:
#反转后面的结点
newhead = self.reverseList(head.next)
#把当前遍历的结点加到后面结点逆序后链表的尾部
head.next.next =head
head.next = None
return newhead
算法性能分析:
由于递归法也只需要对链表进行 次遍历,因此,算法的时间复杂度也为 O(N) ,其中,N为链表的长度。
- 递归法的主要优点是:思路比较直观,容易理解,而且也不需要保存前驱 结点的地址
- 缺点是:算法实现的难度较大,此外,由于递归法需要不断地调用自己,需要 额外的压技与弹枝操作,因此, 与方法 2相比性能会有所降。
就地逆序
[外链图片转存中…(img-OttAYacM-1630078203164)]
移动:第1次指针操作,将当前节点指针cur.next值临时保存到nex,即nex = cur.next, 第2次指针操作,将当前的指针cur.next指向其前一个节点pre, 即cur.next = pre,这样就实现了对单个节点的操作。
操作节点的变量移动,pre结点后移:pre = cur ,cur指向下一个操作节点,即cur = nex,这样通过while循环即可实现对每个节点操作。
特殊情况:链表为空链表、链表为单节点,直接返回即可,无需逆序操作
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
#如果链表为空或者链表中只有一个元素
if head is None or head.next is None:
return head
# 第一步:首结点变成逆转后尾结点
cur = head # 链表首结点
nex = cur.next # 原链表第二个结点
cur.next = None # 断开原链表首结点与第二个结点链接
# 第二步:依次逆转后续结点
pre = cur # 记录前驱结点
cur = nex # 后移一位
while cur.next:
nex = cur.next # 记录后继结点
# 让当前结点指向前驱结点
cur.next = pre # 逆转
pre = cur # 前驱结点后移
cur = nex # 链表后移,遍历
# 第三步:头结点指向原链表尾结点,完成逆转
cur.next = pre # 此时的cur_node应该为:原链表尾结点,最后一次逆转
head.next = cur # 头结点指向尾结点,完成逆转
return head # 返回头结点
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
#如果链表为空或者链表中只有一个元素
if head is None or head.next is None:
return head
cur, pre = head, None
while cur:
nex = cur.next # 记录后继结点
cur.next = pre # 逆转
pre = cur # 前驱结点后移
cur = nex # 链表后移,遍历
return pre
参考
以上是关于剑指 Offer 24. 反转链表的主要内容,如果未能解决你的问题,请参考以下文章
剑指 Offer 24. 反转链表 c++/java详细题解