这里会记录我在 leetcode 刷题中“树“这一块做的题的记录以及想法。会不定期更新,速度取决于做题的速度以及心情。
其中,所有树均用以下定义:
1 2 3 4 5 function TreeNode (val ) { this .val = val; this .left = this .right = null ; }
题目合集 反转二叉树 题号:226 说明:这里运用到了分治的思想,通过递归的方法,逐步对每个节点以及其左右子树进行左右置换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function invert (node ) { if (node == null ) { return node; } let temp = node.left; node.left = node.right; node.right = temp; if (node.left != null ) { invert(node.left); } if (node.right != null ) { invert(node.right); } }
判断是否是同一树 题号:617 说明: 这里同样运用到了分治的思想,通过递归 检查每个节点的左右子树,从而完成全部节点的比较。两个节点相同时,比较其子节点; 一旦出现了空值的情况 ,即到达递归的临界点,对当前状态进行判断并返回一个真值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function isSameTree (p, q ) { if (p !== null && q !== null ) { if (p.val != q.val) { return false ; } } if (p == null && q == null ) { return true ; } if ((p !== null && q === null ) || (p === null && q !== null )) { return false ; } return ( isSameTree( p.left === null ? null : p.left, q.left === null ? null : q.left ) && isSameTree( p.right === null ? null : p.right, q.right === null ? null : q.right ) ); }
判断一棵树是否对称 题号:101 说明:上面一题的变形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function isSymmetric (root ) { if (root == null ) { return true ; } return subLeafSymmetric(root.left, root.right); } function subLeafSymmetric (p, q ) { if (p !== null && q !== null ) { if (p.val != q.val) { return false ; } } if (p == null && q == null ) { return true ; } if ((p !== null && q === null ) || (p === null && q !== null )) { return false ; } return ( subLeafSymmetric( p.left === null ? null : p.left, q.right === null ? null : q.right ) && subLeafSymmetric( p.right === null ? null : p.right, q.left === null ? null : q.left ) ); }
合并两个树(每个相同位置节点值相加)题号:100 说明:还是通过递归的方法,将两个树的每个相对应位置的节点进行相加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function mergeTrees (t1, t2 ) { if (null !== t1 || null !== t2) { let tmp = new TreeNode(0 ); if (t1 != null ) { tmp.val = t1.val; } if (t2 != null ) { tmp.val += t2.val; } tmp.left = mergeTrees( t1 != null ? t1.left : null , t2 != null ? t2.left : null ); tmp.right = mergeTrees( t1 != null ? t1.right : null , t2 != null ? t2.right : null ); return tmp; } else { return null ; } }
构建字符串 题号:606 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function tree2str (t ) { let result = "" ; if (t == null ) { return "" ; } result = t.val.toString(); if (t.right != null ) { return ( result + "(" + tree2str(t.left) + ")" + "(" + tree2str(t.right) + ")" ); } if (t.left == null && t.right == null ) { return result; } if (t.left != null && t.right == null ) { return result + "(" + tree2str(t.left) + ")" ; } }
二叉搜索树中查找值 题号:700 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function searchBST (root, val ) { if (root == null ) { return []; } if (root.val == val) { return root; } if (root.val > val) { return searchBST(root.left, val); } if (root.val < val) { return searchBST(root.right, val); } }
计算二叉树最小深度 题号:111 1 2 3 4 5 6 7 8 9 10 11 12 function minDepth (root ) { if (!root) return 0 ; if (!root.left && !root.right) return 1 ; let result = 1 ; let left = result + minDepth(root.left); let right = result + minDepth(root.right); if (left == 1 && right != 1 ) return right; if (left != 1 && right == 1 ) return left; return right < left ? right : left; }
计算二叉树最大深度 题号:104 1 2 3 4 5 6 7 8 9 10 function maxDepth (root ) { if (!root) return 0 ; if (!root.left && !root.right) return 1 ; let result = 1 ; let left = result + maxDepth(root.left); let right = result + maxDepth(root.right); return right > left ? right : left; }
检查二叉树所有节点数值是否相同 题号:965 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function isUnivalTree (root ) { if (!root) return true if (root.left && root.right) { if ((root.left.val == root.right.val) && (root.left.val == root.val)) { return isUnivalTree(root.left) && isUnivalTree(root.right) } else { return false } } if (!root.left && !root.right) { return true } if (!root.left && root.right) { if (root.right.val == root.val) { return isUnivalTree(root.right) } else { return false } } if (root.left && !root.right) { if (root.left.val == root.val) { return isUnivalTree(root.left) } else { return false } } };
最大二叉树 题号:654 说明:个人觉得这道题和快速排序所用到的分治思想简直如出一辙。先在数组中找到最大值,记作根节点。然后以此跟节点作为划分,递归算出左右子数组的最大数值,记作左右子节点,再各自进行划分,直到叶子节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 var constructMaximumBinaryTree = function (nums ) { if (nums.length < 1 ) { return null } let max = getMax(nums) let maxIndex = getIndex(max, nums) let result = new TreeNode(max) if (maxIndex == 0 ) { result.left = null result.right = constructMaximumBinaryTree(nums.slice(1 )) } else if (maxIndex == nums.length - 1 ) { result.right = null result.left = constructMaximumBinaryTree(nums.slice(0 , nums.length-1 )) } else { result.left = constructMaximumBinaryTree(nums.slice(0 , maxIndex)) result.right = constructMaximumBinaryTree(nums.slice(maxIndex+1 , nums.length)) } return result }; var getMax = function (nums ) { let max = 0 ; for (let i = 0 ; i < nums.length; i++) { if (nums[i] > max) { max = nums[i] } } return max } var getIndex = function (num, arr ) { for (let i = 0 ; i < arr.length; i++) { if (arr[i] == num) { return i } } }