文章目录
一、链表和数组
1.1 数组
在内存中,数组是一块连续的区域,数组需要预留空间,在使用前申请占内存的大小。这样插入数据和删除数据的效率都很低,插入数据时,这个位置后面的数据在内存中都要往后面移;删除数据时,这个数据后面的数据都要往前移。数组是连续的知道每一个数据的内存地址,可以直接找到给数据的地址。并且不利于扩展,数组定义的空间不够时要重新定义数组。
1.2 链表
在内存中可以存在任何地方,不要求连续。每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个地址。增删数据比数组操作更加容易,比如在电影院有十个位置,来了个人要坐第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行(第三个人被删除了),这样所有人的位置都不会动。
但是在这样查找数据的的效率很低,不具有随机访问性。所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起。
1.3 链表和数组各自优缺点
链表 | 数组 | |
---|---|---|
优点 | 插入删除速度快;内存利用率高;大小无固定,拓展灵活 | 随机访问性强;查找速度快 |
缺点 | 不能随机查找,必须从第一个开始遍历,查找效率低 | 插入和删除效率低;要有足够的连续内存空间;数组大小固定不能动态拓展 |
1.3 链表和数组复杂度比较
数组 | 链表 | |
---|---|---|
读取 | O(1) | O(n) |
插入 | O(n) | O(1) |
删除 | O(n) | O(1) |
二、二叉树
2.1 完全二叉树与非完全二叉树的顺序存储
2.1 二叉链表与三叉链表
2.3 递归解决二叉树路径查找问题
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点
的路径,这条路径上所有节点值相加等于目标和 targetSum 。叶子节点 是指没有子节点的节点。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
var hasPathSum = function(root, targetSum) {
if(root==null) return false;
if(root.left==null&&root.right==null&&root.val==targetSum) return