[剑指offer] 6.从尾到头打印链表

题目:输入一个链表的头节点,按链表值从尾到头的顺序返回一个ArrayList。

样例
输入:[2, 3, 5]
返回:[5, 3, 2]

首先想到反转链表,然后就可以从头到尾的输出了,但是这样会改变原来链表的结构,而通常打印是只读操作,这里假设这道题也不允许修改链表结构。

思路1:借助数组反转

从头到尾将链表打印到数组中,将数组反转输出。

复杂度分析
时间复杂度:O(n),因为 遍历一趟数组,以及reverse()的时间复杂度均为 O(n),因此最终时间复杂度也为 O(n)。
空间复杂度:O(n),使用了额外的数组。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def printListReversingly(self, head):
        """
        :type head: ListNode
        :rtype: List[int]
        """
        if not head:  # 空链表测试
            return []
        ls = []
        cur = head  # 
        while cur is not None:
            ls.append(cur.val) #正序存入,也可倒序ls.insert(0,cur.val)
            cur = cur.next
        return ls[::-1]  # 倒序输出,还可以:
        # ls.reverse
        # return ls

注:
Python List 的 insert() 方法用于将指定对象插入列表的指定位置。

list.insert(index, obj) 

index – 对象 obj 需要插入的索引位置。
obj – 要插入列表中的对象。

【1】一定注意是小括号insert( ) 不是. 以及[ ] , 每次都错在这里!
【2】 正序存入可以append,可以insert(val),而倒序存入是ls.insert(0, value),
【3】append的是.val,倒序输出除了[::-1]还可以 ls.reverse(),return ls,但是不可以直接 return ls.reverse()

思路2:栈

这个问题肯定要遍历链表,遍历的顺序是从头到尾,但输出是从尾到头,
后进先出,符合栈的特点。
因此可以在遍历时,把每个节点都压入栈,遍历完整个链表之后再从栈顶开始输出,即为逆序。

class Solution(object):
    def reversePrint(self, head):
        """
        :type head: ListNode
        :rtype: List[int]
        """
        if not head:
            return []
        cur=head
        stack,res=[],[]
        while cur:
            stack.append(cur.val)  # 这里如果存cur,后面res就要存 stack.pop().val
            cur=cur.next
        while stack:
            res.append(stack.pop())
        return res

复杂度分析
时间复杂度:O(n),因为push的时间复杂度为 O(n),pop 的时间复杂度为 O(n)。
空间复杂度:O(n),使用了额外的 数组 和 栈。

思路3:递归

已经想到了栈,而递归本质上就是一个栈结构, 因此也可以用递归来实现。
每访问一个节点的时候,先递归输它后面的节点,再输出该节点自身。

当链表非常长的时候,会导致函数调用的层级很深,就有可能导致函数调用栈溢出,因此用栈基于循环实现的鲁棒性更好。

class Solution(object):
    def reversePrint(self, head):
        res=self.recursive(head)
        return res
    def recursive(self,node):
        if node:
            return self.recursive(node.next)+[node.val]
        else:
            return []
###### 另一种写法
class Solution(object):
    def reversePrint(self, head):
        if not head:
            return []
        return self.reversePrint(head.next)+[head.val]

复杂度分析
时间复杂度:O(n),递归 n次,时间复杂度为 O(n),递归函数中的操作时间复杂度为 O(1),总时间复杂度为 O(n)xO(1)=O(n)。
空间复杂度:O(n),递归将占用链表长度的栈空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值