遍历树算法2 - Solve tree problems recursively

首先定义一棵树node

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.this

代码

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))spa

clipboard.png

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

代码

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.
最后再对左右节点进行持续的遍历。code

代码

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.blog

代码

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;
    }
相关文章
相关标签/搜索