相同的树
解法1:JSON骚操作
var isSameTree = function(p, q) {
return JSON.stringify(p) == JSON.stringify(q)
};
解法2:递归判断
var isSameTree = function(p, q) {
if(!q && !p) return true;
if(q && p && q.val && p.val &&
isSameTree(q.left,p.left) &&
isSameTree(q.right,p.right)
)return true
return false
};
或者写成
var isSameTree = function(p, q) {
if(q===null || p===null){
if(q===null && p===null){
return true
}
return false
}else{
if(q.val===p.val){
return isSameTree(q.left,p.left) && isSameTree(q.right,p.right)
}
else{
return false
}
}
};
对称二叉树
解法1:递归
思路:递归结束条件
# 1. 两个节点都为空
# 2. 一个为空,另一个非空
# 3. 都为非空,但是值不相等
# 4. 都为非空,但是值相等(再次进入递归)
var isSymmetric = function(root) {
if(!root) return false;
function Compare(q,p){
if(!q && !p){
return true;
}
if(!q || !p){
return false;
}
return q.val === p.val && Compare(p.left,q.right)&&Compare(p.right,q.left)
}
return Compare(root.left,root.right)
};
二叉树的最大深度
解法1:js、Math.max()
var maxDepth = function(root) {
return root === null ?
0 : Math.max(maxDepth(root.left),maxDepth(root.right))+1
};
将有序数组转化为二叉搜索树
解法1:js
二叉搜索树:(百度百科)
它或者是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
二叉搜索树的中序遍历为升序
var sortedArrayToBST = function(nums) {
if(nums.length === 0) return null;
let mid = Math.floor(nums.length / 2);
let node = new TreeNode(nums[mid]);
let left = nums.slice(0,mid);
let right = nums.slice(mid+1);
node.left =sortedArrayToBST(left);
node.right=sortedArrayToBST(right);
return node;
};
平衡二叉树
解法1:递归
检查左子树是否为平衡树,并求出左子树深度
检查右子树是否为平衡树,并求出右子树深度
检查左右子树是否平衡,并根据左右子树深度计算当前深度
var isBalanced = function f(root) {
if(!root) return true;
const left =f(root.left)
const right = f(root.right)
if(left===false||right===false) return false
return Math.abs(left-right)>1 ? false : Math.max(left,right)+1
};
或者
var isBalanced = function (root) {
if(!root) return true
const dfs = root =>{
if(!root) return 0
return 1 + Math.max(dfs(root.left),dfs(root.right))
}
if(Math.abs(dfs(root.left)-dfs(root.right))>1){
return false
}else{
if(isBalanced(root.left) && isBalanced(root.right)){
return true
}else{
return false
}
}
};
二叉树的最小深度
解法1:js
var minDepth = function(root) {
if(root===null) return 0
if(root.left===null) {
return minDepth(root.right)+1;
}
if(root.right===null){
return minDepth(root.left)+1;
}
if(root.left!==null && root.right!==null){
return Math.min(minDepth(root.left),minDepth(root.right))+1
}
};
路径zong h3e
解法1:TypeScript
// DFS 基于递归
function hasPathSum(root: TreeNode | null, targetSum: number): boolean {
if (root === null) {
return false;
}
targetSum -= root.val;
if (!root.left && !root.right && targetSum === 0) {
return true;
}
return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
};
或者
var hasPathSum = function(root, targetSum) {
if(!root) return false;
return dfs(root,targetSum);
};
function dfs(root, target){
if (!root) {
return false;
}
target -= root.val;
if(!root.left && !root.right){
return !target;
}
return dfs(root.left,target) || dfs(root.right,target);
}
翻转二叉树
解法1:js
var invertTree = function(root) {
if(!root) return null;
[root.left,root.right]=[root.right,root.left]
invertTree(root.left);
invertTree(root.right);
return root;
};
二叉搜索树的最近公共祖先
解法1:
节点均小于root,那么递归到root的左子树
节点均大于root,那么递归到root的右子树
位于root左右,那么显然root就是最近公共祖先
function lowestCommonAncestor(root, p, q){
if(root === null || root === p || root === q) {
return root
}
var left = lowestCommonAncestor(root.left, p, q)
var right = lowestCommonAncestor(root.right, p, q)
if(left !== null && right !== null) {
return root
}
return left !== null ? left : right
}
二叉树的后序遍历
首先遍历左子树,然后遍历右子树,最后访问根结点
解法1:递归
var postorderTraversal = function(root, res=[]) {
if(root!==null){
postorderTraversal(root.left,res);
postorderTraversal(root.right,res);
res.push(root.val);
}
return res;
};
解法2:迭代
var postorderTraversal = function(root) {
let stack =[]
let result = []
while(root || stack.length){
while(root){
stack.push(root)
result.push(root.val)
root = root.right
}
root = stack.pop()
root = root.left
}
return result.reverse()
};
二叉树的中序遍历
解法1:迭代
先遍历左子树->根节点->右子树
var inorderTraversal = function(root) {
let stack = []
let result = []
while(root || stack.length){
while(root){
stack.push(root)
root = root.left
}
root = stack.pop()
result.push(root.val)
root = root.right
}
return result;
};
二叉树的所有路径
解法1:递归
var binaryTreePaths = function(root) {
if(root===null) return ;
let res=[],temp=[]
const T =(root)=>{
if(!root) return
temp.push(root.val)
if(!root.left && !root.right){
res.push(temp.join('->'))
}
T(root.left)
T(root.right)
temp.pop()
}
T(root)
return res
};
左叶子之和
解法1:js
判断节点是否是左叶子节点,如果是则将它的和累计起来
var sumOfLeftLeaves = function(root) {
if(root===null) return 0;
let sum = 0;
if(root.left!=null && root.left.left==null && root.left.right==null){
sum += root.left.val
}
return sumOfLeftLeaves(root.left)+sumOfLeftLeaves(root.right)+sum;
};
二叉搜索树中的众数
解法1:
var findMode = function(root) {
if(!root) return []
let res = []
let max = 0, current = 0
let pre = root.val
const dfs = (node) =>{
if(!node ) return
dfs(node.left)
if(node.val == pre){
current++
if(current > max){
max = current
res =[node.val]
}
else if(current == max){
res.push(node.val)
}
pre = node.val
}else{
pre = node.val
current = 1
if(current > max){
res = [node.val]
max = current
}
else if(current == max){
res.push(node.val)
}
}
dfs(node.right)
}
dfs(root)
return res
};
解法2:
var findMode = function(root) {
if(!root) return
let temp = {
}
let max = 0
const dfs = root => {
if(!root) return
dfs(root.left)
if(!temp[root.val]){
temp[root.val] = 0
}
temp[root.val]++
max = Math.max(max,temp[root.val])
dfs(root.right)
}
dfs(root)
return Object.keys(temp).filter(k=>temp[k]===max)
};
二叉搜索树的最小绝对差
解法1:中序遍历
var arr = []
var getMinimumDifference = function(root) {
arr = []
TreeNode(root)
let i = 0 , min = null
while(i<arr.length-1){
min = min && min < arr[i+1] - arr[i] ? min : arr[i+1]-arr[i]
i++
}
return min
};
var TreeNode = function(root){
if(root){
TreeNode(root.left)
arr.push(root.val)
TreeNode(root.right)
}
}