1. 程式人生 > >LeetCode-Most Frequent Subtree Sum

LeetCode-Most Frequent Subtree Sum

一、Description

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.

題目大意:

給定一個二叉樹,找出出現次數最多的子樹和。子樹和指的是當前結點的所有子結點的值加上當前結點的總和,如果有多個,則返回所有的子樹和,次序隨意。

Examples 1 Input:

  5
 /  \
2   -3

return [2, -3, 4], since all the values happen only once, return all of them in any order.(subtree sum of root:4 = 5 + 2 - 3)

Examples 2 Input:

  5
 /  \
2   -5

return [2], since 2 happens twice, however -5 only occur once.(subtree sum of root:2 = 5 + 2 - 5)

二、Analyzation

我首先定義了一個map和一個優先佇列,Word的val用來儲存每個結點的子樹和,count表示子樹和出現的次數。先通過遞迴函式將所有結點置為對應的子樹和的值(從葉子結點開始往上遞迴),每次計算一個子樹和就放進map中,並更新對應的次數,最後通過優先佇列,將最上面的結點依次放入list中,只要當前出隊的Word的count小於前一次出隊的Word的count,說明子樹和出現次數最多的Word已經全部放入list中,最後返回result陣列即可。

三、Accepted code

class Word {
    int val;
    int count;
    public Word(int val, int count) {
        this.val = val;
        this.count = count;
    }
}
class Solution {
    PriorityQueue<Word> queue = new PriorityQueue<>(new Comparator<Word>() {
        @Override
        public int compare(Word o1, Word o2) {
            return o2.count - o1.count;
        }
    });
    Map<Integer, Integer> map = new HashMap<>();
    public int[] findFrequentTreeSum(TreeNode root) {
        if (root == null) {
            return new int[0];
        }
        help(root);
        for (Integer i : map.keySet()) {
            Word word = new Word(i, map.get(i));
            queue.add(word);
        }
        List<Integer> list = new ArrayList<>();
        while (!queue.isEmpty()) {
            Word word = queue.poll();
            list.add(word.val);
            if (!queue.isEmpty() && queue.peek().count < word.count) {
                break;
            }
        }
        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        System.out.println(Arrays.toString(result));
        return result;
    }
    public void help(TreeNode root) {
        if (root.left != null) {
            help(root.left);
        }
        if (root.right != null) {
            help(root.right);
        }
        root.val += (root.left == null ? 0 : root.left.val) + (root.right == null ? 0 : root.right.val);
        if (map.containsKey(root.val)) {
            int value = map.get(root.val);
            map.put(root.val, value + 1);
        } else {
            map.put(root.val, 1);
        }
    }
}