前言:剑指offer刷题系列
问题:
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例:
输入:head = [1,3,2]
输出:[2,3,1]
非递归思路:
- 我首先是定义一个空数组 number,用来存储链表中的值。
- 然后判断数组是否为空,如果数组为空,则返回空数组[],如果数组不为空,则将链表的头结点head赋给node,目的是保证head头结点不丢失。
- 接着使用while循环,将链表的值一个个push到新声明的number数组中,node指向node的后一个节点node.next。
- 最后用reverse函数逆向输出number数组的元素,此时就使链表内的值反转过来了。
基于上述思考,代码如下:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {number[]}
*/
var reversePrint = function(head) {
let number = []
if(head == null) return []
let node = head
while(node){
number.push(node.val)
node = node.next
}
return number.reverse()
};
执行结果如下图:
递归思路:
- 这段代码是一个递归版本的函数,用于反向打印链表中的元素。它接受一个参数
head,表示链表的头节点。 - 使用 return 语句来返回函数的值。这里使用了三元运算符来进行条件判断。
- 函数首先检查 head 是否为null。如果是,表示链表为空,返回一个空数组。否则,就会递归调用 自身,传入 head.next 作为参数,这样就可以递归地获取链表剩余部分的反转数组。
- 当递归到链表末尾时,函数会返回一个包含最后一个节点值的数组。然后,在返回过程中,每一层递归都会使用 concat 函数将当前节点的值添加到数组的末尾,head.val 表示当前节点的值。
- 最终,函数会返回一个包含链表所有元素的数组,元素顺序与链表中元素顺序相反。
基于上述思考,代码如下:
/**
* @param {ListNode} head
* @return {number[]}
*/
var reversePrint = function(head) {
return head == null ? [] : reversePrint(head.next).concat(head.val)
};
执行结果如下图:
非递归比递归在运行速度和内存消耗上都要优秀,递归真的非常慢。
python版本:
最近在学习python,所以加了一个题解,思路就是简单的将链表里面的值加入到新声明的数组中,使用到了append()函数,python不知道为什么不能使用+=赋值,我现在不太记得了,之后再去了解一下
数组的逆序输出直接用的是,arr[a:b:-1],第一个数a表想要输出的第一个字符的位置,第二个数b表想要输出的最后一个字符的位置,最后一个数写上-1,表示从后往前逆序输出,如果要正序输出,不用加第三个数。
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
arr = []
while head:
arr.append(head.val)
head = head.next
return arr[::-1]
执行结果如下图:
学到的知识点:
- concat() 是一个函数,用于连接两个或多个数组或值。在 JavaScript 中,它是一个数组方法,可以用来将一个或多个数组连接在一起,形成一个新的数组。题中是将head.val的值添加到当前数组的末尾。
- 记忆:连接猫concat别写错了嗷
- reverse 函数是一个数组方法,可以用来反转数组中的元素顺序。它会改变原数组,并返回原数组的引用。注意,返回的是反转后的数组。 reverse 函数会保留空位。如果源数组是稀疏的,那么空位对应的新索引也会被删除,并且也变成空位。