链表-剑指offer6从尾到头打印链表-简单-20210810
1. 题目描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例:
输入:head = [1,3,2]
输出:[2,3,1]
2. 题目解答
2.1 反转/=堆栈(效率优)
时间复杂度:O(n),reverse()的时间复杂度为O*(*n),遍历了一遍数组,复杂度也为 O(n)
空间复杂度:O(n),使用了额外的res
思路:从头到尾将链表打印到数组中,返回反转后的结果即可
class Solution(object):
def reverse_list(self, head):
res = []
while head:
res.append(head.val)
head = head.next
return res[::-1]
2.2 堆栈
时间复杂度:O(n),push的时间复杂度为 O(n),pop的时间复杂度为 O(n)
空间复杂度:O(n),使用了额外的 res
和 堆栈【实际直接用数组倒序也是堆栈的思想】
思路:利用堆栈先进后出的特点,先依次将元素压入堆栈中,然后将所有元素从堆栈中弹出,即可实现反转
class Solution(object):
def reverse_list2(self, head):
stack = []
while head:
stack.append(head.val)
head = head.next
res = []
while stack:
res.append(stack.pop())
return res
2.3 递归(递归费时)
时间复杂度:O(n),递归 n 次,时间间复杂度为 O(n);递归函数中的操作时间复杂度为 O(1),总时间复杂度为O(n)×O(1)=O(n)
空间复杂度:O(n),递归将占用链表长度的栈空间
思路:先走至链表末端,回溯时依次将节点值加入列表 ,这样就可以实现链表值的倒序输出
-
① 递归阶段:每次传入
head.next
,以head == None
(即走到链表尾部的结点)为递归终止条件,此时返回空列表 [] -
② 回溯阶段:每次返回
当前list + 当前结点值[head.val]
,实现倒序输出
class Solution(object):
def reverse_list3(self, head):
if not head: return []
return self.reverse_list3(head.next) + [head.val]
3. 测试用例
1. 特殊输入测试:空链表
2. 功能测试:输入的链表有多个/只有1个结点
if __name__ == '__main__':
# Test Case
head1 = []
head2 = [2]
head3 = [1, 3, 2]
L = LinkList.LinkList()
head1 = L.init_list(head1)
head2 = L.init_list(head2)
head3 = L.init_list(head3)
Solution = Solution()
print(Solution.reverse_list(head1))
print(Solution.reverse_list2(head1))
print(Solution.reverse_list3(head1))
print(Solution.reverse_list(head2))
print(Solution.reverse_list2(head2))
print(Solution.reverse_list3(head2))
print(Solution.reverse_list(head3))
print(Solution.reverse_list2(head3))
print(Solution.reverse_list3(head3))