二叉树的前序:中左右
二叉树的中序:左中右
二叉树的后序:左右中
题型一:
合并二叉树

思路:同时遍历两棵树相同的结点,即使其中一棵树该结点为null,将他们相加后覆盖某棵树的该结点。利用递归表达更清楚。涉及到BFS和DFS算法。
var mergeTrees = function(root1, root2) {if(root1 == null)return root2;if(root2 == null)return root1;root1.val += root2.val;root1.left = mergeTrees(root1.left,root2.left);root1.right = mergeTrees(root1.right,root2.right);return root1;};//深度
二叉树的前序遍历
二叉树的中序遍历
二叉树的后序遍历
思路:递归遍历
var preorderTraversal = function(root) {var out = [];function getVal(tree) {if(tree == null)return;else out.push(tree.val);//中getVal(tree.left);//左getVal(tree.right);//右//根据前中后序来变换位置。前:中左右中:左中右后:左右中}getVal(root);return out;};
二叉树的最大深度

思路:递归调用,边界条件是该结点为null
var maxDepth = function(root){return root==null?0:Math.max(maxDepth(root.left),maxDepth(root.right))+1;}
翻转二叉树


(这段简直太草了)
思路:递归
var invertTree = function(root) {if(root == null)return null;const left = invertTree(root.left);const right = invertTree(root.right);root.right = left;root.left = right;return root;};
对称二叉树
思路:递归,判断一个树是否对称,看左右子树是否相同,然后判断左右子树的右左子树是否相同。
var isSymmetric = function(root) {function check(a,b){if(a==null&&b==null)return true;else if(a==null||b==null)return false;else return a.val==b.val && check(a.left,b.right) && check(a.right,b.left);}return check(root,root);};
路径总和
思路:递归,判断是否是叶子结点,是的话就看值符不符合,不是叶子结点就拿和减去当前结点数值来递归
const hasPathSum = (root, sum) => {if(root == null)return false;if(root.left==null&&root.right==null){return sum - root.val == 0;}else return hasPathSum(root.left,sum-root.val)||hasPathSum(root.right,sum-root.val);}
两数之和 IV - 输入 BST
思路:该题二叉树默认是搜索二叉树,即为左边的子节点小于根节点,右边的子节点大于根节点,这样的中序排下来是一个升序数组,然后用双指针指向头尾来查找答案。
var findTarget = function(root, k) {var out = [];function seek(tree){if(!tree){return ;}seek(tree.left);out.push(tree.val);seek(tree.right);}seek(root);let head = 0;let tail =out.length-1;while(head<tail){if(out[head]+out[tail] == k)return true;else if(out[head]+out[tail]<k){head++}else tail--;}return false;};
二叉搜索树的最近公共祖先
思路:当此结点都大于pq时,说明祖先结点在左子树;都小于时,说明在右子树。一旦一大一小或者有个相等时,说明此时的结点即为祖先节点。
var lowestCommonAncestor = function(root, p, q) {while(true){if(root.val>p.val&&root.val>q.val){root = root.left;}else if(root.val<p.val&&root.val<q.val){root = root.right;}else{break;}}return root;};
或者:两次遍历,得到去两个结点的路径,记录在数组中,然后寻找两个数组相同的路径,直到不同为止最大的索引即为祖先结点所在位置。
题型九:
二叉树的层序遍历
思路:用一个数组从根节点开始记录,初始时数组仅有根节点,此时将目的数组开放[0],将根节点从记录数组移动到目的数组,并检查是否有子节点,有的话将子节点移动到记录数组,将子节点当做根节点循环此步骤直到没有子节点放入记录结点。
var levelOrder = function(root) {const ret = [];if (!root) {return ret;}const q = [];q.push(root);while (q.length !== 0) {const currentLevelSize = q.length;ret.push([]);for (let i = 1; i <= currentLevelSize; ++i) {const node = q.shift();ret[ret.length - 1].push(node.val);if (node.left) q.push(node.left);if (node.right) q.push(node.right);}}return ret;};
剑指 Offer 32 - I. 从上到下打印二叉树
思路:
广度优先算法,用队列先进先出的性质,先将根节点放入队列,将根节点数据放入目标数组,然后监测左右节点并放入队列,重复以下步骤。因为先进先出,这样会根据从上到下的顺序进出。
const levelOrder = root => {if (!root) return [];// 创建队列,并将根节点入队const queue = [root];const res = [];while (queue.length) {// 获取根节点,根节点出队const n = queue.shift();// 访问队头res.push(n.val);// 队头的子节点依次入队n.left && queue.push(n.left);n.right && queue.push(n.right);}return res;};
剑指 Offer 28. 对称的二叉树
思路:
递归
var isSymmetric = function(root) {function judge(left,right){if(left == null&&right == null)return true;if(left == null||right == null||left.val != right.val) return false;return judge(left.left,right.right)&&judge(left.right,right.left);}return root==null?true:judge(root.left,root.right);};
