JIAKAOBO

LeetCode

venmo
wechat

感谢赞助!

  • ㊗️
  • 大家
  • offer
  • 多多!

Problem

Given the root of a binary tree, return all duplicate subtrees.

For each kind of duplicate subtrees, you only need to return the root node of any one of them.

Two trees are duplicate if they have the same structure with the same node values.

Example 1:

img

Input: root = [1,2,3,4,null,2,4,null,null,4]
Output: [[2,4],[4]]

Example 2:

img

Input: root = [2,1,1]
Output: [[1]]

Example 3:

img

Input: root = [2,2,2,3,null,3,null]
Output: [[2,3],[3]]

Constraints:

  • The number of the nodes in the tree will be in the range [1, 5000]
  • -200 <= Node.val <= 200

Code

class Solution {
    class Node{
        int id;
        int count;

        public Node(int id, int count) {
            this.id = id;
            this.count = count;
        }
    }

    int currId = 0;
    HashMap<String, Node> map;
    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
        map = new HashMap<>();
        List<TreeNode> res = new LinkedList<>();

        postorder(root, res);
        return res;
    }

    private int postorder(TreeNode root, List<TreeNode> res) {
        if (root == null) return -1;

        int leftId = postorder(root.left, res);
        int rightId = postorder(root.right, res);

        String treeStr = leftId + "," + root.val + "," + rightId;

        if(map.containsKey(treeStr)) {
            Node node = map.get(treeStr);
            node.count++;
            if (node.count == 2) res.add(root);
        } else {
            Node node = new Node(currId, 1);
            map.put(treeStr, node);
            currId++;
        }

        return map.get(treeStr).id;
    }
}
class Solution {
    Map<String, TreeNode> trees;
    Map<String, Integer> count;

    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
        trees = new HashMap<>();
        count = new HashMap<>();
        List<TreeNode> res = new ArrayList<>();
        helper(root);

        for (String key : count.keySet()) {
            if (count.get(key) >= 2) {
                res.add(trees.get(key));
            }
        }

        return res;
    }

    public void helper(TreeNode root) {
        if (root == null) return;

        helper(root.left);

        String encoded = encodeTreeNode(root);
        trees.put(encoded, root);
        count.put(encoded, count.getOrDefault(encoded, 0) + 1);

        helper(root.right);
    }

    private String encodeTreeNode(TreeNode root) {
        if (root == null) return "";

        StringBuilder sb = new StringBuilder();

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            TreeNode curr = queue.poll();

            if (curr == null) {
                sb.append("null ");
                continue;
            }

            int val = curr.val;
            sb.append(val + " ");
            queue.offer(curr.left);
            queue.offer(curr.right);
        }

        return sb.toString();
    }
}