剑指 Offer 06. 从尾到头打印链表

112 阅读1分钟

题目

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

示例 1:

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

 

限制:

0 <= 链表长度 <= 10000

解析

这道题目较为简单,是关于链表的遍历,有两种解法: 遍历和递归。

遍历

由于链表节点只有next指针指向后一个节点,从前往后遍历,把每一个节点的值添加到结果数组res中,然后使用数组的reverse方法翻转即可

递归

  1. 递归的终止条件是 node == null, 此时链表中所有的节点已经访问完
  2. 在递归过程收集当前访问节点的值node.val,使用unshift方法逐个添加到数组头部,从而实现了数组的反转
  3. 递归调用_reversePrint(next, res), 传入下一个节点和结果数组,直到 node === null, 递归终止

参考代码

遍历

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {number[]}
 */
var reversePrint = function(head) {
     // 声明返回结果数组 res;
     const res = [];
     // 声明 p 指针 指向 head 头结点
     let p = head;
     
     // 当p == null 时, 终止循环 
     while(p != null) {
         // 数组 res 添加 当前遍历节点的值
         res.push(p.val);
         // 更新 p 指针,指向下一个节点
         p = p.next;
     }
     // 反转数组 res   
     return res.reverse();
};

递归

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {number[]}
 */
var reversePrint = function(head) {
    
    // 声明返回结果数组 res
    const res = [];

    // 定义递归函数
    const _reversePrint = (node, res) => {
        // 递归终止条件,当head == null, 此时已遍历完链表
        if (node == null) {
            return 
        }
        // 把当前节点的值添加到 res, 这里用unshift向数组头部添加,实现数组的反转
        res.unshift(node.val);
        // 获取下一个节点
        const next = node.next;
        // 递归 next 节点,传入 res 数组保存最终结果
        _reversePrint(next, res);
    }
    // 调用递归函数,传入 head 头结点,和 res 数组
    _reversePrint(head, res);

    // 返回结果res
    return res;
    
};

原题链接

剑指 Offer 06. 从尾到头打印链表