Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ค้นหาทรีย่อยที่ซ้ำกันใน C++


สมมติว่าเรามีต้นไม้ไบนารี เราต้องหาต้นไม้ย่อยที่ซ้ำกันทั้งหมด ดังนั้นสำหรับทรีย่อยที่ซ้ำกันแต่ละประเภท เราต้องส่งคืนโหนดรูทของทรีย่อยใดทรีหนึ่งในทรีเหล่านี้ สมมติว่าเรามีต้นไม้เช่น −

ค้นหาทรีย่อยที่ซ้ำกันใน C++

ทรีย่อยที่ซ้ำกันคือ −

ค้นหาทรีย่อยที่ซ้ำกันใน C++

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -

  • สร้างอาร์เรย์ ret, ทำแผนที่ m
  • กำหนดวิธีการแบบเรียกซ้ำแก้ปัญหา () สิ่งนี้จะใช้โหนดเป็นอินพุต ทำงานเป็น −
  • ถ้าโหนดเป็นโมฆะ ให้คืนค่า -1
  • x :=ค่าของโหนดเป็นสตริง จากนั้นเชื่อม “#” เข้ากับมัน
  • ซ้าย :=แก้ (ซ้ายของโหนด) ขวา :=แก้ (ทางขวาของโหนด)
  • x :=x concatenate “#” concatenate left, concatenate “#” concatenate right
  • เพิ่ม m[x] ขึ้น 1
  • ถ้า m[x] เป็น 2 ให้แทรกโหนดใน ret
  • ผลตอบแทน x
  • จากการเรียกเมธอดหลัก Solve(root) และ return 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, ]