【每日算法】从尾到头打印链表

76 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

题目

剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode)

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

输入:head = [1,3,2]
输出:[2,3,1]

思路 一

分析

首先我们先放松一下,来一个简单直接粗暴的解法

题目要求的只是结果顺序反过来的数组,那我们可以偷鸡,定义一个数组,按顺序迭代链表,依次将每个节点的值用一个数组存储起来,最后输出的时候把数组做一个反转就可以啦~

一通操作~过了哈哈~信心+1

实现

function reversePrint(head: ListNode | null): number[] {
    const result:number[] = []
    let node = head
    while(node) {
        result.push(node.val)
        node = node.next
    }
    result.reverse()
    return result
};

思路 二

分析

好了现在我们开始正儿八经的分析一下

一般涉及到链表的题,就离不开使用迭代或者递归

迭代

使用迭代一般都需要有明确的边界,要么从头往后遍历,要么从尾往头遍历

对于链表这类数据的遍历,只能从头往后遍历

这个时候为了得到一个逆序的输出结果,可以考虑使用unshift方法,在结果头部添加元素,

这样直接遍历完成后,我们就可以得到一个逆序的结果了

递归

首先要理解递归实际上是利用了栈的数据结构在执行函数

也就是先进入,后输出(这就满足了我们需要逆序输出结果的需求——链表头先进入,但是最后输出)

首先还是递归函数两部走

  • 终止条件

很明显,当 node === null 时跳出

  • 循环体

先执行下一个循环函数

在把当前值添加到我们的结果数组中

实现

// 迭代
function reversePrint(head: ListNode | null): number[] {
    const result:number[] = []
    let node = head
    while(node) {
        result.unshift(node.val)
        node = node.next
    }
    return result
};
​
// 递归
function reversePrint(head: ListNode | null): number[] {
    const result:number[] = []
​
    function handle(node: ListNode | null) {
        // 终止条件
        if (node === null) {
            return
        } 
        // 循环体
        handle(node.next)
        result.push(node.val)
    }
​
    handle(head)
​
    return result
};