LeetCode——Find Duplicate Subtrees

本文介绍了一种查找二叉树中所有重复子树的方法。通过先序遍历并记录每个子树的序列化字符串,可以有效地找出具有相同结构和节点值的重复子树。

Question

Given 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 same node values.

Example 1:

        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4

The following are two duplicate subtrees:

      2
     /
    4

and

    4

Therefore, you need to return above trees' root in the form of a list.

Solution

遍历所有子树的情况,遍历每棵子树的时候,采用先序遍历,但是得把空节点考虑进去,这样只有结构一样,遍历得到的字符串才一样。 也就是说,先序遍历(不考虑空孩子节点)的结果相同,并不意味着树的结构相同。 但是考虑了以后就是唯一的了。

Code

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        if (root == NULL)
            return vector<TreeNode*>();
        Trace(root);
        Compare();
        return res;
    }
    // 遍历所有子树
    void Trace(TreeNode* root) {
        if (root != NULL)
            sub1.push_back(root);
        if (root->left != NULL)
            Trace(root->left);
        if (root->right != NULL)
            Trace(root->right);
    }
    void Compare() {
       for (int i = 0; i < sub1.size(); i++) {
           string tmp = "";
           SubTreeStr(sub1[i], tmp);
           if (count.find(tmp) == count.end()) {
               count[tmp] = 1;
           } else
               count[tmp] += 1;
           if (childs.find(tmp) == childs.end())
               childs[tmp] = sub1[i];
       }
        map<string, int>::iterator iter;
        for (iter = count.begin(); iter != count.end(); iter++) {
            if (iter->second > 1)
                res.push_back(childs[iter->first]);
        }
    }
    void SubTreeStr(TreeNode* root1, string& str) {
        // 考虑空节点,才能保证先序遍历的唯一性
        if (root1 == NULL) {
            str += "NULL";
        } else {
            str += to_string(root1->val);
            SubTreeStr(root1->left, str);
            SubTreeStr(root1->right, str);
        }            
    }
    vector<TreeNode*> sub1, res;
    map<string, int> count;
    map<string, TreeNode*> childs;
};

转载于:https://www.cnblogs.com/zhonghuasong/p/7588731.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值