链表: head 或 node
node.val 表示一个元素的值;
node = node.next 遍历到下一个元素。
1、遍历链表,依次把遍历到的元素值 unshift(从头插入)到一个数组中
2、递归函数(本质是栈解法), 递归本身与栈后进先出的原理一致。
通过递归到链表的最后一个元素开始,push到数组中。需要注意是否会因为链表过长导致栈溢出。
3、先将链表反转,再遍历输出链表。(可能不允许改变函数输入的原链表)
var reversePrint = function(head) {
const nums = [];
const reverseP = function (head) {
if(head != null) {
reverseP(head.next);
nums.push(head.val);
}
}
reverseP(head);
return nums;
};
在链表的操作中,添加一个哑节点(dummy node),让它的指针指向链表的头节点,这样在删除节点的时候,就不需要再判断删除的是不是头结点了。
let dummy = new ListNode(0, head);
// 设置哑结点的数据域为0,指针域指向链表的头结点:dummy.val = 0, dummy.next = head;
理解指针:指针不受链表的限制,是可以任意赋值,去指向某一节点。
递归:
- 终止条件
if (n <= 2) return 1; // 其中,f(0)=0,f(1)=1
- 用递推公式来表示递归问题
f(n) = f(n-1) + f(n-2)
递归是某个重复动作的形式化描述。如果一个问题 A 可以分解为若干子问题 B、C、D,可以假设子问题 B、C、D 已经解决,在此基础上思考如何解决问题 A。并且只需要思考 A 与 B、C、D 两层之间的关系即可,不需要一层一层往下思考子问题与子子问题等之间的关系(递归只能考虑当前层和下一层的关系)。
node.next.next = node;
node.next = null;
树
树的遍历:后序遍历