【Lintcode】628。最大サブツリー

タイトルアドレス:

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;
    }
}

時空の複雑さ O(n)

方法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;
    }
}

時間の複雑さ O(n) 、スペース h ああ)

公開された387元の記事 ウォンの賞賛0 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_46105170/article/details/105467790