二叉树遍历应用
测试工程师正在测试某款新型扫地机器人。工程师设计了一个形如二叉树(根节点记为root)的测试路径,扫地机器人自路径对应的根节点出发,一直行进至路径尽头(即二叉树叶节点)。如果这个路口的左右子节点都非空,机器人选择左转或右转的概率相等;如果这个路口的左右子节点仅一侧非空,则机器人选择非空侧走。工程师给每个路口标记了数字,并且仅在标记数字target的所有路口设置了监控摄像机。请问扫地机器人被监控至少拍到一次的概率是多少?1 <= 树的节点数 <= 10000。
输入:root = [1, 2, 3, 2, 5, 6, 2], target = 2
输出:0.75
解释:数组按二叉树层次遍历的顺序记录了标记数字。从1出发,从左侧走到2的概率为0.5(被拍到),从右侧走到3的概率为0.5,从3继续出发走到2的概率为0.5(被拍到),所以结果为0.5 + 0.5 * 0.5 = 0.75。
即:左侧分支被拍到的概率为0.5(圆圈的2是0.5,继续走到2或5,不会增加被拍概率,也不会降低被拍概率),右侧分支被拍到的概率为0.25(圆圈的2),合计为0.75。

输入:
输出:
root = [1, null, 3, 2, 2], target = 2
输出:
1
解答:
构造二叉树然后递归统计概率
private class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } } public float calProbability(Integer[] tree, int target) { if (tree.length == 0) { return 0; } //先构造树 TreeNode root = new TreeNode(tree[0]); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int index = 1; while (!queue.isEmpty() && index < tree.length) { int size = queue.size(); for (int i = index; i < index + 2 * size; i++) { TreeNode node = queue.poll(); int left = i; int right = i + 1; if (null != tree[left]) { node.left = new TreeNode(tree[left]); queue.offer(node.left); } else { node.left = null; } if (null != tree[right]) { node.right = new TreeNode(tree[right]); queue.offer(node.right); } else { node.right = null; } i++; } index = index + 2 * size; } return getProbability(root, 1, target); } private float getProbability(TreeNode root, float f, int target) { if (target == root.val) { return f; } else if (root.left != null && root.right != null) { return getProbability(root.left, f / 2, target) + getProbability(root.right, f / 2, target); } else if (root.left != null) { return getProbability(root.left, f, target); } else if (root.right != null) { return getProbability(root.right, f, target); } else { return 0; } }
解法二:
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } // 以上为Leetcode二叉树节点定义,下述语句则用于本地构造二叉树用例 public TreeNode left(int val) { this.left = new TreeNode(val); return this; } public TreeNode right(int val) { this.right = new TreeNode(val); return this; } public TreeNode left() { return this.left; } public TreeNode right() { return this.right; } // 以下语句将构造一棵层次顺序为[1, 2, 3, 2, 5, 6, 2]的满二叉树 // TreeNode root = trust.new TreeNode(1); root.left(2).right(3); // root.left().left(2).right(5); root.right().left(6).right(2); } private double helper(TreeNode node, int target, double probability) { // 不保证正确性,因为递归很难分析-_- if (node == null) { return 0; } if (node.val == target) { return probability; } double leftProb = 0.0, rightProb = 0.0; if (node.left != null) { leftProb = (node.right != null) ? 0.5 : 1; } if (node.right != null) { rightProb = (node.left != null) ? 0.5 : 1; } return probability * (helper(node.left, target, leftProb) + helper(node.right, target, rightProb)); } public double captureProbability(TreeNode root, int target) { return helper(root, target, 1.0); }
测试用例如下:
TreeNode root = trust.new TreeNode(1); root.left(2).right(3); root.left().left(2).right(5); root.right().left(6).right(2); System.out.println(trust.captureProbability(root, 2)); //0.75 root = trust.new TreeNode(1); root.right(3); root.right().left(2).right(2); System.out.println(trust.captureProbability(root, 2)); //1.0 root = trust.new TreeNode(1); root.right(3); root.right().left(3).right(4); System.out.println(trust.captureProbability(root, 2)); //0.0