{"id":1390,"date":"2017-12-31T15:18:34","date_gmt":"2017-12-31T23:18:34","guid":{"rendered":"http:\/\/zxi.mytechroad.com\/blog\/?p=1390"},"modified":"2019-05-07T20:42:49","modified_gmt":"2019-05-08T03:42:49","slug":"leetcode-652-find-duplicate-subtrees","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/tree\/leetcode-652-find-duplicate-subtrees\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 652. Find Duplicate Subtrees"},"content":{"rendered":"\n\n\n<p>\n\n652.&nbsp;Find Duplicate SubtreesMedium730151FavoriteShare<\/p>\n\n\n\n<p>Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any&nbsp;<strong>one<\/strong>&nbsp;of them.<\/p>\n\n\n\n<p>Two trees are duplicate if they have the same structure with same node values.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<p>The following are two duplicate subtrees:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted; crayon:false\">        1\n       \/ \\\n      2   3\n     \/   \/ \\\n    4   2   4\n       \/\n      4<\/pre>\n\n\n\n<p>  2<br> \/<br>4<\/p>\n\n\n\n<p>and<\/p>\n\n\n\n<p>4<\/p>\n\n\n\n<p>Therefore, you need to return above trees&#8217; root in the form of a list.\n\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/zxi.mytechroad.com\/blog\/wp-content\/uploads\/2017\/12\/652-ep146-1.png\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution 1: Serialization <\/strong><\/h2>\n\n\n\n<p>Time complexity: O(n^2)<br>Space complexity: O(n^2) <\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua\n\/\/ Runtime: 29 ms\nclass Solution {\npublic:\n    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {\n        unordered_map<string, int> counts;\n        vector<TreeNode*> ans;\n        serialize(root, counts, ans);\n        return ans;\n    }\nprivate:\n    string serialize(TreeNode* root, unordered_map<string, int>& counts, vector<TreeNode*>& ans) {\n        if (!root) return \"#\";\n        string key = to_string(root->val) + \",\" \n                     + serialize(root->left, counts, ans) + \",\" \n                     + serialize(root->right, counts, ans);\n        if (++counts[key] == 2)\n            ans.push_back(root);\n        return key;\n    }\n};\n<\/pre>\n<\/div><\/div>\n\n\n\n<p><strong>Solution 2: int id for each unique subtree<\/strong><\/p>\n\n\n\n<p>Time complexity: O(n)<br>Space complexity: O(n)<\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua\n\/\/ Runtime: 8 ms\nclass Solution {\npublic:\n  vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {\n    unordered_map<long, pair<int,int>> counts;    \n    vector<TreeNode*> ans;\n    getId(root, counts, ans);\n    return ans;\n  }\nprivate:\n  int getId(TreeNode* root, \n            unordered_map<long, pair<int,int>>& counts,\n            vector<TreeNode*>& ans) {\n    if (!root) return 0;\n    long key = (static_cast<long>(static_cast<unsigned>(root->val)) << 32) +\n               (getId(root->left, counts, ans) << 16) +\n                getId(root->right, counts, ans);    \n    auto& p = counts[key];\n    if (p.second++ == 0)\n      p.first = counts.size();    \n    else if (p.second == 2)\n      ans.push_back(root);\n    return p.first;\n  }\n};\n<\/pre>\n<\/div><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>652.&nbsp;Find Duplicate SubtreesMedium730151FavoriteShare Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[164,45],"tags":[114,177,94,225,28],"class_list":["post-1390","post","type-post","status-publish","format-standard","hentry","category-medium","category-tree","tag-hash","tag-medium","tag-serialization","tag-subtree","tag-tree","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/1390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/comments?post=1390"}],"version-history":[{"count":20,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/1390\/revisions"}],"predecessor-version":[{"id":5166,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/1390\/revisions\/5166"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=1390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=1390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=1390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}