当前位置:网站首页>LeetCode每日一题(968. Binary Tree Cameras)
LeetCode每日一题(968. Binary Tree Cameras)
2022-07-03 09:01:00 【wangjun861205】
You are given the root of a binary tree. We install cameras on the tree nodes where each camera at a node can monitor its parent, itself, and its immediate children.
Return the minimum number of cameras needed to monitor all nodes of the tree.
Example 1:
Input: root = [0,0,null,0,0]
Output: 1
Explanation: One camera is enough to monitor all nodes if placed as shown.
Example 2:
Input: root = [0,0,null,0,null,0,null,null,0]
Output: 2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.
Constraints:
- The number of nodes in the tree is in the range [1, 1000].
- Node.val == 0
为树中每个节点赋予一个编号, 这个不麻烦, left = curr * 2 + 1, right = curr * 2 + 2, 假设 dp[i][is_covered][need_place]代表的是树中第 i 个节点在是否被摄像头覆盖到(is_covered)和是不是一定要强制安装一个摄像头在该节点(need_place)的情况下以第 i 个节点为根节点的子树所需要的最小摄像头数量。这样我们就可以把情况分为三种, 一种是需要强制安装摄像头 need_place == true, 这样它的左右两个子节点都会被覆盖到(我们是自上而下, 不管父节点), 那结果就是 dp[i*2+1][true][false] + dp[i*2+2][true][false] + 1, 如果不需要强制安装, 那我们就看是否覆盖的情况(is_covered), 如果当前节点已经被覆盖了, 我们可以在当前节点放置摄像头, 那跟上面说的这种情况是一样的, dp[i*2+1][true][false] + dp[i*2+2][true][false] + 1, 也可以不放置, 因为当前节点已经被覆盖, 所以即使我们不在当前节点放置摄像头,那子节点也没有强制放置摄像头的必要, 那结果就是 dp[i*2+1][false][false] + dp[i*2+2][false][false], 这两种情况取小的返回。最后一种是既没有要求强制放置也没有被覆盖到, 那这样我们可以在当前节点放置摄像头(同上),也可以强制在左侧子节点或者右侧子节点放置摄像头, dp[i*2+1][false][true]或者 dp[i*2+2][false][true], 这三种情况取最小值
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
impl Solution {
fn dp(root: &Option<Rc<RefCell<TreeNode>>>, val: i32, is_covered: bool, need_place: bool, cache: &mut HashMap<(i32, bool, bool), i32>) -> i32 {
if let Some(node) = root {
if need_place {
let left = if let Some(c) = cache.get(&(val * 2 + 1, true, false)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, true, false, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, true, false)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, true, false, cache)
};
cache.insert((val, is_covered, need_place), left + right + 1);
return left + right + 1;
}
if is_covered {
let curr_place = {
let left = if let Some(c) = cache.get(&(val * 2 + 1, true, false)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, true, false, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, true, false)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, true, false, cache)
};
left + right + 1
};
let curr_pass = {
let left = if let Some(c) = cache.get(&(val * 2 + 1, false, false)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, false, false, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, false, false)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, false, false, cache)
};
left + right
};
let ans = curr_place.min(curr_pass);
cache.insert((val, is_covered, need_place), ans);
return ans;
}
let curr_place = {
let left = if let Some(c) = cache.get(&(val * 2 + 1, true, false)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, true, false, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, true, false)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, true, false, cache)
};
left + right + 1
};
let left_place = {
if node.borrow().left.is_none() {
i32::MAX
} else {
let left = if let Some(c) = cache.get(&(val * 2 + 1, false, true)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, false, true, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, false, false)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, false, false, cache)
};
left + right
}
};
let right_place = {
if node.borrow().right.is_none() {
i32::MAX
} else {
let left = if let Some(c) = cache.get(&(val * 2 + 1, false, false)) {
*c
} else {
Solution::dp(&node.borrow().left, val * 2 + 1, false, false, cache)
};
let right = if let Some(c) = cache.get(&(val * 2 + 2, false, true)) {
*c
} else {
Solution::dp(&node.borrow().right, val * 2 + 2, false, true, cache)
};
left + right
}
};
let ans = curr_place.min(left_place).min(right_place);
cache.insert((val, is_covered, need_place), ans);
return ans;
}
0
}
pub fn min_camera_cover(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut cache = HashMap::new();
Solution::dp(&root, 0, false, false, &mut cache)
}
}
边栏推荐
- Problems in the implementation of lenet
- [graduation season | advanced technology Er] another graduation season, I change my career as soon as I graduate, from animal science to programmer. Programmers have something to say in 10 years
- Crawler career from scratch (I): crawl the photos of my little sister ① (the website has been disabled)
- Spark 概述
- Vscode编辑器右键没有Open In Default Browser选项
- Recommend a low code open source project of yyds
- Detailed steps of windows installation redis
- [kotlin learning] classes, objects and interfaces - define class inheritance structure
- Liteide is easy to use
- Navicat, MySQL export Er graph, er graph
猜你喜欢
![[kotlin learning] classes, objects and interfaces - classes with non default construction methods or attributes, data classes and class delegates, object keywords](/img/ee/d982fd9e1f2283e09ad1a81d0b61b5.png)
[kotlin learning] classes, objects and interfaces - classes with non default construction methods or attributes, data classes and class delegates, object keywords

Flink-CDC实践(含实操步骤与截图)
![[point cloud processing paper crazy reading frontier version 11] - unsupervised point cloud pre training via occlusion completion](/img/76/b92fe4549cacba15c113993a07abb8.png)
[point cloud processing paper crazy reading frontier version 11] - unsupervised point cloud pre training via occlusion completion

Flink学习笔记(十一)Table API 和 SQL

Hudi 集成 Spark 数据分析示例(含代码流程与测试结果)

【Kotlin学习】类、对象和接口——带非默认构造方法或属性的类、数据类和类委托、object关键字

With low code prospect, jnpf is flexible and easy to use, and uses intelligence to define a new office mode

MySQL installation and configuration (command line version)
![[set theory] order relation (chain | anti chain | chain and anti chain example | chain and anti chain theorem | chain and anti chain inference | good order relation)](/img/fd/c0f885cdd17f1d13fdbc71b2aea641.jpg)
[set theory] order relation (chain | anti chain | chain and anti chain example | chain and anti chain theorem | chain and anti chain inference | good order relation)

Liteide is easy to use
随机推荐
【点云处理之论文狂读经典版8】—— O-CNN: Octree-based Convolutional Neural Networks for 3D Shape Analysis
We have a common name, XX Gong
[kotlin learning] operator overloading and other conventions -- overloading the conventions of arithmetic operators, comparison operators, sets and intervals
LeetCode 535. Encryption and decryption of tinyurl
Hudi 快速体验使用(含操作详细步骤及截图)
Banner - Summary of closed group meeting
Flink学习笔记(八)多流转换
【点云处理之论文狂读前沿版11】—— Unsupervised Point Cloud Pre-training via Occlusion Completion
Introduction to the basic application and skills of QT
[point cloud processing paper crazy reading classic version 12] - foldingnet: point cloud auto encoder via deep grid deformation
Run flash demo on ECS
Data mining 2021-4-27 class notes
How to check whether the disk is in guid format (GPT) or MBR format? Judge whether UEFI mode starts or legacy mode starts?
用Redis实现分布式锁
Serializer rewrite: update and create methods
LeetCode 57. Insert interval
Crawler career from scratch (I): crawl the photos of my little sister ① (the website has been disabled)
307. Range Sum Query - Mutable
【点云处理之论文狂读前沿版8】—— Pointview-GCN: 3D Shape Classification With Multi-View Point Clouds
[set theory] order relation (chain | anti chain | chain and anti chain example | chain and anti chain theorem | chain and anti chain inference | good order relation)