题记
刚刚开始刷题,这次是一道有关数据结构的题目,特别是要了数据结构之链表
:小编在上一篇文章中整理了各种数据结构的简介,需要的小伙伴请转到:
【算法数据结构简介(Python)】非科班小伙伴刷题必备
认识链表
链表以节点为单位,每个元素都是一个独立对象,在内存空间的存储是非连续的。链表的节点对象具有两个成员变量:「值 val
」,「后继节点引用 next
」 。
class ListNode:
def __init__(self, x):
self.val = x # 节点值
self.next = None # 后继节点引用
如下图所示,建立此链表需要实例化每个节点,并构建各节点的引用指向。
# 实例化节点
n1 = ListNode(4) # 节点 head
n2 = ListNode(5)
n3 = ListNode(1)
# 构建引用指向
n1.next = n2
n2.next = n3
既然了解了链表,那咱们开始看题:
题目描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:0 <= 链表长度 <= 10000
题目解析
方法一:递归法
利用递归,先递推至链表末端;回溯时,依次将节点值加入列表,即可实现链表值的倒序输出。
递归解析:
- 终止条件: 当
head == None
时,代表越过了链表尾节点,则返回空列表; - 递推工作: 访问下一节点
head.next
; - 回溯阶段:Python返回 当前
list + 当前节点值 [head.val]
;
转化为代码便是:
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
return self.reversePrint(head.next) + [head.val] if head else []
复杂度分析:
- 时间复杂度
O(N)
: 遍历链表,递归N
次。 - 空间复杂度
O(N)
: 系统递归需要使用O(N)
的栈空间。
方法二:辅助栈法
链表只能 从前至后 访问每个节点,而题目要求 倒序输出 各节点值,这种 先入后出 的需求可以借助 栈 来实现。
算法流程:
入栈: 遍历链表,将各节点值 push 入栈。
出栈: 将各节点值 pop 出栈,存储于数组并返回。
复杂度分析:
- 时间复杂度
O(N)
: 入栈和出栈共使用O(N)
时间。 - 空间复杂度
O(N)
: 辅助栈 stack 使用O(N)
的额外空间。
下一步直接返回倒序数组return stack[::-1]
。
Python代码:
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
stack = []
while head:
stack.append(head.val)
head = head.next
return stack[::-1] # 表示从列表的最后一个元素复制到第一个元素
PyCharm中运行调试方法
class Solution(object):
def reversePrint(self, head): # 方法1:递归
"""
:type head: ListNode
:rtype: List[int]
"""
return self.reversePrint(head.next) + [head.val] if head else []
def reversePrint_1(self, head): # 方法2:辅助栈
stack = []
while head:
stack.append(head.val)
head = head.next
return stack[::-1] # 表示从列表的最后一个元素复制到第一个元素
class ListNode:
# 链表的构造 初始化
def __init__(self, x):
self.val = x
self.next = None
# 实例化节点
n1 = ListNode(1) # 节点 head
n2 = ListNode(3)
n3 = ListNode(2)
# 构建引用指向
n1.next = n2
n2.next = n3
solution = Solution()
print(solution.reversePrint_1(n1))
输出:
[2, 3, 1]
如果直接输入head = [1, 3, 2]
则会报错:
AttributeError: 'list' object has no attribute 'val'
AttributeError: 'list' object has no attribute 'next'
原因是列表没有val
和next
,在这里只能是链表,所以需要先通过ListNode
创建链表再调用函数。