首先定义一棵树

var root = {
   val: 1,
   left:{
     val: 2,
     left: {
        val: 3,
        left: {
            val: 5
        }
     },
     right: {
        val: 4,
        right: {
            val: 6
        }
     }
   },
   right:{
       val: 7,
       left: {
           val: 8
       },
       right:{
           val: 9,
           right: {
               val: 10,
               left: {
                  val: 11,
                  right: {
                     val: 12
                  }
               }
           }    
       }
   } 
};

Max Depth of Binary Tree 计算二叉树最大深度

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 最大深度是指从根节点到最远的叶节点经过的节点个数。

思路

节点如果为空, 则 return 0.
节点如果有左节点或者右节点, 则 return depth + 1.
换算成公式则为:
fn(n) = 0, if null;
fn(n) = 1 + max(f(n.left), f(n.right))

clipboard.png

以这课树为例,
nodeA的深度 = 1 + max(nodeB的深度, nodeC的深度)
nodeB没有子节点,所以nodeB的深度为1.
nodeC有子节点 [D, E], 所以nodeC的深度为2.
所以 nodeA的最大深度 = 1 + max(1, 2) = 2.

代码

var maxDepth= function(root) {
  if(root == null) return 0;
  return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
};

console.warn(maxDepth(root));  // 6

Min Depth of Binary Tree 计算二叉树最小深度

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 最小深度是指从根节点到最近的叶节点经过的节点个数。

思路

节点如果为空, 则 return 0.
节点如果有左节点或者右节点, 则 return depth + 1.
换算成公式则为:
fn(n) = 0, if null;
fn(n) = 1 + min(f(n.left), f(n.right))

clipboard.png

以这课树为例,
nodeA的深度 = 1 + min(nodeB的深度, nodeC的深度)
nodeB没有子节点,所以nodeB的深度为1.
nodeC有子节点 [D, E], 所以nodeC的深度为2.
所以 nodeA的最小深度 = 1 + min(1, 2) = 2.

代码

var minDepth= function(root) {
  if(root == null) return 0;
  return 1 + Math.min(minDepth(root.left), minDepth(root.right));
};

console.warn(minDepth(root));  // 3

Path Sum of Binary Tree 计算二叉树路径之和

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 判定一个从根节点到叶子节点的路径之和是否和给定的数值相等。

思路

进行DFS深度优先遍历,依次将 (sum - root.val) 传递给递归函数的sum值。
如果root不存在,直接return false.
如果root不存在left和right节点, 说明是叶子节点,若sum值等于val, 则return true.
最后再对左右节点进行持续的遍历。

代码

var hasPathSum = function(root, sum) {
  if (!root) return false;
  if (!root.left && !root.right && root.val === sum) return true;
  return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
};

console.warn(hasPathSum(root, 11));  // true
console.warn(hasPathSum(root, 13));  // true
console.warn(hasPathSum(root, 16));  // true
console.warn(hasPathSum(root, 45));  // true
console.warn(hasPathSum(root, 50));  // true

Symmetric Binary Tree 判断二叉树是否对称

this binary tree [1,2,2,3,4,4,3] is symmetric. 这棵树[1,2,2,3,4,4,3]是对称的。
But the following [1,2,2,null,3,null,3] is not. 这棵树[1,2,2,null,3,null,3]不是对称的。

思路

如果根节点不存在,则直接return true.
如果node节点不存在左右子树, 则return true.
如果node节点存在左子树,或者右子树, 则return false.
如果node节点存在左右子树,但是节点的值不相等, 则return false.
接下来比较左子树的左节点和右子树的右节点, 左子树的右节点和右子树的左节点, 都相同时return true.

代码

var isSymmetric = function(root) {
    if(!root) return true;
    
    function compareNodes(left, right) {
        if (!left && !right) return true;
        if (!left || !right) return false;
        if (left.val !== right.val) return false;
        
        return (compareNodes(left.left, right.right) && compareNodes(left.right, right.left));
    }
    return compareNodes(root.left, root.right);
};

isSymmetric(root);   // false

var root2 = {
   val: 1,
   left:{
     val: 2,
     left: {
        val: 3,
        left: {
            val: 5
        }
     },
     right: {
        val: 4,
        right: {
            val: 6
        }
     }
   },
   right:{
       val: 2,
       right: {
        val: 3,
        right: {
            val: 5
        }
     },
     left: {
        val: 4,
        left: {
            val: 6
        }
     }
   } 
};
isSymmetric(root2);  // true

二叉树反转

其实就是二叉树的左右节点互换,深度遍历。

    function reverseLeftRightNodes(node) {
        if(node === null || node === undefined) return;
        
        let temp = node.left;
        node.left = node.right;
        node.right = temp;
        
        reverseLeftRightNodes(node.left);
        reverseLeftRightNodes(node.right);
        return node;
    }

肾导
1.7k 声望105 粉丝

渐渐成熟的前端工程师。