You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class07;
// 本题测试链接 : https://leetcode.com/problems/binary-tree-cameras/
public class Code02_MinCameraCover {
public static class TreeNode {
public int value;
public TreeNode left;
public TreeNode right;
}
public static int minCameraCover1(TreeNode root) {
Info data = process1(root);
return (int) Math.min(data.uncovered + 1, Math.min(data.coveredNoCamera, data.coveredHasCamera));
}
// 潜台词x是头节点x下方的点都被覆盖的情况下
public static class Info {
public long uncovered; // x没有被覆盖x为头的树至少需要几个相机
public long coveredNoCamera; // x被相机覆盖但是x没相机x为头的树至少需要几个相机
public long coveredHasCamera; // x被相机覆盖了并且x上放了相机x为头的树至少需要几个相机
public Info(long un, long no, long has) {
uncovered = un;
coveredNoCamera = no;
coveredHasCamera = has;
}
}
// 所有可能性都穷尽了
public static Info process1(TreeNode X) {
if (X == null) { // base case
return new Info(Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
}
Info left = process1(X.left);
Info right = process1(X.right);
// x uncovered x自己不被覆盖x下方所有节点都被覆盖
// 左孩子: 左孩子没被覆盖,左孩子以下的点都被覆盖
// 左孩子被覆盖但没相机,左孩子以下的点都被覆盖
// 左孩子被覆盖也有相机,左孩子以下的点都被覆盖
long uncovered = left.coveredNoCamera + right.coveredNoCamera;
// x下方的点都被coveredx也被cover但x上没相机
long coveredNoCamera = Math.min(
// 1)
left.coveredHasCamera + right.coveredHasCamera,
Math.min(
// 2)
left.coveredHasCamera + right.coveredNoCamera,
// 3)
left.coveredNoCamera + right.coveredHasCamera));
// x下方的点都被coveredx也被cover且x上有相机
long coveredHasCamera =
Math.min(left.uncovered, Math.min(left.coveredNoCamera, left.coveredHasCamera))
+ Math.min(right.uncovered, Math.min(right.coveredNoCamera, right.coveredHasCamera))
+ 1;
return new Info(uncovered, coveredNoCamera, coveredHasCamera);
}
public static int minCameraCover2(TreeNode root) {
Data data = process2(root);
return data.cameras + (data.status == Status.UNCOVERED ? 1 : 0);
}
// 以x为头x下方的节点都是被coveredx自己的状况分三种
public static enum Status {
UNCOVERED, COVERED_NO_CAMERA, COVERED_HAS_CAMERA
}
// 以x为头x下方的节点都是被covered得到的最优解中
// x是什么状态在这种状态下需要至少几个相机
public static class Data {
public Status status;
public int cameras;
public Data(Status status, int cameras) {
this.status = status;
this.cameras = cameras;
}
}
public static Data process2(TreeNode X) {
if (X == null) {
return new Data(Status.COVERED_NO_CAMERA, 0);
}
Data left = process2(X.left);
Data right = process2(X.right);
int cameras = left.cameras + right.cameras;
// 左、或右,哪怕有一个没覆盖
if (left.status == Status.UNCOVERED || right.status == Status.UNCOVERED) {
return new Data(Status.COVERED_HAS_CAMERA, cameras + 1);
}
// 左右孩子,不存在没被覆盖的情况
if (left.status == Status.COVERED_HAS_CAMERA || right.status == Status.COVERED_HAS_CAMERA) {
return new Data(Status.COVERED_NO_CAMERA, cameras);
}
// 左右孩子,不存在没被覆盖的情况,也都没有相机
return new Data(Status.UNCOVERED, cameras);
}
}