二叉树刷题(四)

137 阅读3分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

前面写了几天二叉树题目,有需要的童鞋请冲 二叉树刷题(一) 二叉树刷题(二) 二叉树刷题(三), 这篇继续刷几道二叉树的题。

一、判断是否为树的子结构

剑指 Offer 26. 树的子结构

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如: 给定的树 A:

     3
    / \
   4   5
  / \
 1   2

给定的树 B:

   4 
  /
 1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

  • 输入:A = [1,2,3], B = [3,1]
  • 输出:false

示例 2:

  • 输入:A = [3,4,5,1,2], B = [4,1]
  • 输出:true

限制:0 <= 节点个数 <= 10000

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/sh… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路 要判断B是否为A的子树,先遍历A的所有节点,找到与B相等的节点。再遍历B树中所有节点 和刚才找到的节点的子树 是否一致,若一致则返回true,否则返回false。 代码实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
var isMatch = function(A, B) {
    // 若B为空,说明遍历到底了,前面都一样,所以B是A的子树
    if(B == null) return true;
    // 若A为空,B不为空,说明B不是A的子树,所以返回false
    if(A == null) return false;
    // 当两个树的当前节点不相等时,说明B不是A的子树,所以返回false
    if(A.val != B.val) return false;
    // 递归检查两个树的左右子树是否一样
    return isMatch(A.left, B.left) && isMatch(A.right, B.right);
}
/**
 * @param {TreeNode} A
 * @param {TreeNode} B
 * @return {boolean}
 */
var isSubStructure = function(A, B) {
    if(A== null || B==null) return false;
    // 若当前节点与子树的根节点相等 并且 两个树的所有节点相等,则返回true
    if((A.val == B.val) && isMatch(A,B)) return true;
    // 否则遍历A的左右子树,继续查找与B相同的节点
    return isSubStructure(A.left, B) || isSubStructure(A.right, B)
};

二、监控二叉树

968. 监控二叉树

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

示例 1:

image.png

  • 输入:[0,0,null,0,0]
  • 输出:1
  • 解释:如图所示,一台摄像头足以监控所有节点。

示例 2:

  • 输入:[0,0,null,0,null,0,null,null,0]
  • 输出:2
  • 解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。

提示:

  • 给定树的节点数的范围是 [1, 1000]。
  • 每个节点的值都是 0。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/bi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  1. 设定0表示无摄像头,不被监控的节点;
  2. 设定1表示无摄像头,被监控的节点;
  3. 设定2表示有摄像头,被自身监控的节点;

后序遍历所有节点,

  • 当左右节点中有一个为0的节点时,当前节点需要安装一个摄像头,监控自身和其左右子节点,返回2;
  • 当左右节点中有一个为2的节点时,当前节点被监控,返回1;
  • 当左右节点为两个1时,当前节点设为0,但可以不加监控,可以留给其父节点加。

代码实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
var ans = 0;
var dfs = function(root) {
    if(root == null) return 1;
    var l = dfs(root.left);
    var r = dfs(root.right);

    if(l == 0 || r == 0) {
        ans ++;
        return 2;
    } else if(l == 2 || r == 2) {
        return 1;
    }
    return 0;
}
/**
 * @param {TreeNode} root
 * @return {number}
 */
var minCameraCover = function(root) {
    if(root == null) return 0;
    if(dfs(root) == 0) ans ++;
    return ans;
};