当前位置:网站首页>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)
}
}
边栏推荐
- Integrated use of interlij idea and sonarqube
- Introduction to the basic application and skills of QT
- 【点云处理之论文狂读前沿版12】—— Adaptive Graph Convolution for Point Cloud Analysis
- Database execution error: SQL_ mode only_ full_ group_ by:
- Go language - JSON processing
- IDEA 中使用 Hudi
- Install database -linux-5.7
- 【点云处理之论文狂读经典版13】—— Adaptive Graph Convolutional Neural Networks
- [point cloud processing paper crazy reading classic version 9] - pointwise revolutionary neural networks
- [untitled] use of cmake
猜你喜欢

About the configuration of vs2008+rade CATIA v5r22

We have a common name, XX Gong

Crawler career from scratch (II): crawl the photos of my little sister ② (the website has been disabled)

2022-2-14 learning the imitation Niuke project - send email

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

CSDN markdown editor help document

Alibaba cloud notes for the first time

Jenkins learning (II) -- setting up Chinese

2022-2-14 learning xiangniuke project - Session Management
![[point cloud processing paper crazy reading classic version 11] - mining point cloud local structures by kernel correlation and graph pooling](/img/40/e0c7bad60b19cafa467c229419ac21.png)
[point cloud processing paper crazy reading classic version 11] - mining point cloud local structures by kernel correlation and graph pooling
随机推荐
Django operates Excel files through openpyxl to import data into the database in batches.
Move anaconda, pycharm and jupyter notebook to mobile hard disk
Go language - JSON processing
Hudi integrated spark data analysis example (including code flow and test results)
LeetCode 75. Color classification
Apply for domain name binding IP to open port 80 record
[kotlin puzzle] what happens if you overload an arithmetic operator in the kotlin class and declare the operator as an extension function?
[kotlin learning] classes, objects and interfaces - define class inheritance structure
Common formulas of probability theory
[point cloud processing paper crazy reading classic version 8] - o-cnn: octree based revolutionary neural networks for 3D shape analysis
Banner - Summary of closed group meeting
【Kotlin学习】类、对象和接口——带非默认构造方法或属性的类、数据类和类委托、object关键字
[point cloud processing paper crazy reading classic version 13] - adaptive graph revolutionary neural networks
【点云处理之论文狂读前沿版13】—— GAPNet: Graph Attention based Point Neural Network for Exploiting Local Feature
【点云处理之论文狂读经典版12】—— FoldingNet: Point Cloud Auto-encoder via Deep Grid Deformation
Idea uses the MVN command to package and report an error, which is not available
Powerdesign reverse wizard such as SQL and generates name and comment
[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)
Crawler career from scratch (3): crawl the photos of my little sister ③ (the website has been disabled)
The server denied password root remote connection access