在 C++ 中查詢重複子樹


假設我們有一棵二叉樹。我們必須找到所有重複的子樹。因此,對於每種重複的子樹,我們都必須返回其中任何一個的根節點。假設我們有一棵這樣的樹 −

重複的子樹是 −

為解決此問題,我們將按照以下步驟操作 −

  • 建立一個數組 ret,繪製一個對映 m
  • 定義一個遞迴方法 solve()。這將以 node 作為輸入。它的工作方式如下 −
  • 如果 node 為空,則返回 -1
  • x := node 的值表示為字串,然後在後面連線 “#” 。
  • left := node 的左側解決,right := node 的右側解決
  • x :=x 連線 “#” 連線 left,連線 “#” 連線 right
  • m[x] 增加 1
  • 如果 m[x] 為 2,則將 node 插入到 ret 中
  • 返回 x
  • 從主方法呼叫 solve(root) 並返回 ret

讓我們看看以下實現,以更好地理解 −

示例

 現場演示

#include <bits/stdc++.h>
using namespace std;
class TreeNode{
   public:
      int val;
      TreeNode *left, *right;
      TreeNode(int data){
         val = data;
         left = right = NULL;
      }
};
void insert(TreeNode **root, int val){
   queue<TreeNode*> q;
   q.push(*root);
   while(q.size()){
      TreeNode *temp = q.front();
      q.pop();
      if(!temp->left){
         if(val != NULL)
            temp->left = new TreeNode(val);
            else
               temp->left = new TreeNode(0);
               return;
            } else {
               q.push(temp->left);
            }
            if(!temp->right){
               if(val != NULL)
                  temp->right = new TreeNode(val);
               else
                  temp->right = new TreeNode(0);
                  return;
               } else {
                  q.push(temp->right);
               }
            }
         }
         TreeNode *make_tree(vector<int> v){
            TreeNode *root = new TreeNode(v[0]);
            for(int i = 1; i<v.size(); i++){
               insert(&root, v[i]);
            }
            return root;
         }
         void tree_level_trav(TreeNode*root){
            if (root == NULL) return;
            cout << "[";
            queue<TreeNode *> q;
            TreeNode *curr;
            q.push(root);
            q.push(NULL);
            while (q.size() > 1) {
               curr = q.front();
               q.pop();
               if (curr == NULL){
                  q.push(NULL);
            } else {
            if(curr->left)
            q.push(curr->left);
            if(curr->right)
            q.push(curr->right);
         if(curr->val == 0 || curr == NULL){
               cout << "null" << ", ";
         } else {
               cout << curr->val << ", ";
         }
      }
   }
   cout << "]"<<endl;
}
class Solution {
public:
  vector <TreeNode*> ret;
   map <string, int> m;
   string solve(TreeNode* node){
      if(!node || node->val == 0){
         return "-1";
      }
      string x = to_string(node->val);
      x += "#";
      string left = solve(node->left);
      string right = solve(node->right);
      x = x + "#" + left + "#" + right;
      m[x]++;
      if(m[x] == 2){
         ret.push_back(node);
      }
      return x;
   }
   vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
      ret.clear();
      m.clear();
      solve(root);
      return ret;
   }
};
main(){
   vector<int> v = {1,2,3,4,NULL,2,4,NULL,NULL,NULL,NULL,4};
   Solution ob;
   TreeNode *root = make_tree(v);
   vector<TreeNode*> trees = ob.findDuplicateSubtrees(root);
   for(TreeNode *t : trees){
      tree_level_trav(t);
   }
}

輸入

[1,2,3,4,null,2,4,null,null,null,null,4]

輸出

[4, ]
[2, 4, ]

更新於: 04-May-2020

98 瀏覽

開啟你的 職業生涯

完成課程即可獲得認證

入門
廣告
© . All rights reserved.