タイトルアドレス:
https://www.lintcode.com/problem/maximum-subtree/description
バイナリツリーを指定すると、最大のサブツリーを見つけ、そのルートを返します。
法律1:分割して征服する。左側のサブツリー、右側のサブツリー、またはルート自体のいずれかに3つの可能性のある結果しかないため、分割統治でそれを行うことができます。ただし、現在のツリーのノード合計が必要なため、左サブツリーと右サブツリーのノード合計を再帰的に解決する必要があり、記録されていない場合は二重計算の問題が発生します。したがって、ハッシュテーブルを使用して各サブツリーのノードの合計を記録し、いくつかの記憶を行います。コードは次のとおりです。
import java.util.HashMap;
import java.util.Map;
public class Solution {
/**
* @param root: the root of binary tree
* @return: the maximum weight node
*/
public TreeNode findSubtree(TreeNode root) {
// write your code here
if (root == null) {
return root;
}
Map<TreeNode, Integer> map = new HashMap<>();
// 空树节点和记为0
map.put(null, 0);
return find(root, map);
}
private TreeNode find(TreeNode root, Map<TreeNode, Integer> map) {
if (root == null) {
return null;
}
TreeNode left = find(root.left, map), right = find(root.right, map);
// 分别计算本树以及左右子树的节点和,
// 由于是递归计算的,所以算完root节点和后左右子树的节点和都已经存在哈希表里了,可以直接拿出来
int sum = sum(root, map), lSum = map.get(left), rSum = map.get(right);
if (left == null && right == null) {
return root;
} else if (right == null) {
return sum >= lSum ? root : left;
} else if (left == null) {
return sum >= rSum ? root : right;
} else {
if (sum >= Math.max(lSum, rSum)) {
return root;
} else {
return lSum >= rSum ? left : right;
}
}
}
private int sum(TreeNode root, Map<TreeNode, Integer> map) {
// 如果已经有了记忆则调取记忆
if (map.containsKey(root)) {
return map.get(root);
}
// 否则递归求解并把结果放进哈希表
map.put(root, sum(root.left, map) + sum(root.right, map) + root.val);
// 最后返回
return map.get(root);
}
}
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) {
val = x;
}
}
時空の複雑さ 。
方法2:DFS。グローバル変数を使用してツリーの最大合計とルートを記録し、DFS中にグローバル変数を更新しながら現在のサブツリーの合計を計算します。コードは次のとおりです。
public class Solution {
int maxSum = Integer.MIN_VALUE;
TreeNode res = null;
/**
* @param root: the root of binary tree
* @return: the maximum weight node
*/
public TreeNode findSubtree(TreeNode root) {
// write your code here
if (root == null) {
return root;
}
// 计算所有子树的和并更新全局变量
sum(root);
return res;
}
private int sum(TreeNode root) {
if (root == null) {
return 0;
}
// 分治
int left = sum(root.left), right = sum(root.right);
int total = left + right + root.val;
if (maxSum < total) {
maxSum = total;
res = root;
}
return total;
}
}
時間の複雑さ 、スペース 。