LeetCode 663. 均匀树划分(树形DP)
作者:互联网
1. 题目
给定一棵有 n 个结点的二叉树,你的任务是检查是否可以通过去掉树上的一条边将树分成两棵,且这两棵树结点之和相等。
样例 1: 输入: 5 / \ 10 10 / \ 2 3 输出: True 解释: 5 / 10 和: 15 10 / \ 2 3 和: 15 样例 2: 输入: 1 / \ 2 10 / \ 2 20 输出: False 解释: 无法通过移除一条树边将这棵树划分成结点之和相等的两棵子树。 注释 : 树上结点的权值范围 [-100000, 100000]。 1 <= n <= 10000
2. 解题
- 自底向上求得每个节点的子树和,更新于节点的 val
- 遍历检查+剪枝,共计2次遍历
- 实际上就是问这棵二叉树是否存在一棵真子树,其节点和等于总节点和的一半。可以两遍DFS,第一遍算出整棵树的节点和,第二遍查看是否有某棵子树的节点和恰好等于整棵树节点和的一半。代码如下:、
public class Solution { private boolean res; private int sum; public boolean checkEqualTree(TreeNode root) { sum = dfs(root, root); if (sum % 2 != 0) { return false; } // 将答案初始化为false res = false; dfs(root, root); return res; } // 返回cur为根的子树的节点和 private int dfs(TreeNode cur, TreeNode root) { if (cur == null) { return 0; } int left = dfs(cur.left, root), right = dfs(cur.right, root); if ((left + right + cur.val) * 2 == sum && cur != root) { res = true; } return left + right + cur.val; } } class TreeNode { int val; TreeNode left, right; public TreeNode(int val) { this.val = val; } }
方法二:
class Solution { Map<Integer, Integer> map = new HashMap<>(); public boolean checkEqualTree(TreeNode root) { if (root == null) return false; int total = getTotal(root); if (total%2 != 0) return false; if (total/2 == 0) return map.getOrDefault(total/2, 0) > 1; return map.containsKey(total/2); } private int getTotal(TreeNode root) { if (root == null) return 0; int total = root.val+getTotal(root.left)+getTotal(root.right); map.put(total, map.getOrDefault(total, 0)+1); return total; } }
标签:return,cur,val,663,TreeNode,total,root,LeetCode,DP 来源: https://www.cnblogs.com/kpwong/p/14717774.html