בדוק אם כל הרמות של שני עץ בינארי הן אנגרמות או לא


רמת קושי קשה
נשאל לעתים קרובות Adobe אמזון בעברית פייסבוק קנאות פורקיטים גריי אורנג '
אֲנַגְרַמָה עץ בינארי תור עֵץ

הצהרת בעיה

הבעיה "בדוק אם כל הרמות של שני עץ בינארי הן אנגרמות או לא" אומרת שאתה מקבל שני עצים בינאריים, בדוק אם כל הרמות של שני העצים הם אנגרמות או לא.

דוגמאות

קֶלֶט

בדוק אם כל הרמות של שני עץ בינארי הן אנגרמות או לא

true

קֶלֶט

בדוק אם כל הרמות של שני עץ בינארי הן אנגרמות או לא

false

אלגוריתם לבדיקה אם כל הרמות של שני עץ בינארי הן אנגרמות או לא

אנחנו נשתמש has has לפתרון בעיה זו. חוצים כל רמה של שתיים עצים בּוֹ זְמַנִית. בעץ הראשון, אחסן את האלמנט ותדירות הרמה הנוכחית ב- a מפת גיבוב ולרמה הנוכחית של העץ השני, אם האלמנט הנוכחי אינו קיים ב- HashMap. כל הרמות אינן אנגרמות. אחרת להפחית את תדירות האלמנט ב- HashMap. אם בסוף המעבר, HashMap ריק, רמה זו של שני העצים היא האנגרמה תמשיך לשלב הבא, אחרת כל הרמות אינן אנגרמות.

  1. צור שניים פרָאק q1 ו- q2, q1 משמש לחציית עץ 1 ו- q2 משמש לחציית q2.
  2. דחף את שורש העץ 1 ל- q1 ואת שורש העץ 2 ל- q2.
  3. בעוד ש- q1 אינו ריק או ש- q2 אינו ריק חזור על שלב 4, 5 ו -6.
  4. צור HashMap לאחסון אלמנטים ותדירות של אלמנטים ברמה הנוכחית. אתחל מספר שלם גודל 1 כגודל של q1. הפעל לולאה מ 0 עד פחות מגודל 1. בכל איטרציה צץ אלמנט מהתור q1 והוסף אותו ל- HashMap. דחפו את ילדי האלמנט הנוכחי אל ה תור.
  5. אתחל מספר שלם גודל 2 כגודל של q2. הפעל לולאה מ 0 עד פחות מגודל 2. בכל איטרציה, צץ אלמנט מהתור q2 ואם אלמנט זה קיים ב- HashMap הפחית את התדירות שלו ב -1, אחרת תחזיר שקר באופן מיידי.
  6. אם בסוף הלולאה, HashMap מכיל אלמנט, להחזיר שקר, אחרת הרמה הזו של שני העצים היא אנגרמות, המשך לשלב הבא.
  7. אם נגיע לכאן, כל המפלסים של שני העצים הם אנגרמות, אז חזור נכון.

קופונים

קוד Java לבדיקה אם כל הרמות של שני עץ בינארי הן אנגרמות או לא

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

class CheckIfAllLevelsOfTwoBinaryTreeAreAnagramsOrNot {
    // class representing node of a binary tree
    static class Node {
        int data;
        Node left, right;

        public Node(int data) {
            this.data = data;
        }
    }

    private static boolean checkIsAnagrams(Node tree1, Node tree2) {
        // create two queues
        Queue<Node> q1 = new LinkedList<>();
        Queue<Node> q2 = new LinkedList<>();
        // add root of tree1 to q1
        q1.add(tree1);
        // add root of tree2 to q2
        q2.add(tree2);

        // while either of q1 or q2 is not empty
        while (!q1.isEmpty() || !q2.isEmpty()) {
            // create a hash map to store freq of elements of a level
            HashMap<Integer, Integer> freq = new HashMap<>();

            // traverse this level of tree1
            int size1 = q1.size();
            for (int i = 0; i < size1; i++) {
                // remove a node from queue
                Node curr = q1.poll();
                // add the element to hash map
                if (freq.containsKey(curr.data)) {
                    freq.put(curr.data, freq.get(curr.data) + 1);
                } else {
                    freq.put(curr.data, 1);
                }

                // add curr's children to queue
                if (curr.left != null)
                    q1.add(curr.left);
                if (curr.right != null)
                    q1.add(curr.right);
            }

            // traverse this level of tree2
            int size2 = q2.size();
            for (int i = 0; i < size2; i++) {
                // remove a node from q2
                Node curr = q2.poll();
                // decrease the frequency of this element in hash map
                if (freq.containsKey(curr.data)) {
                    int frequency = freq.get(curr.data);
                    frequency--;
                    if (frequency == 0) {
                        freq.remove(curr.data);
                    } else {
                        freq.put(curr.data, frequency);
                    }
                } else {
                    return false;
                }

                // add curr's children to queue
                if (curr.left != null)
                    q2.add(curr.left);
                if (curr.right != null)
                    q2.add(curr.right);
            }

            // if there is an element in the hash map
            // the two tree's current levels are not anagrams
            if (freq.size() > 0) {
                return false;
            }
        }

        // all the levels are anagrams, return true
        return true;
    }

    public static void main(String[] args) {
        // Example 1
        Node tree1_1 = new Node(5);
        tree1_1.left = new Node(4);
        tree1_1.right = new Node(3);
        tree1_1.left.left = new Node(2);
        tree1_1.left.right = new Node(1);

        Node tree2_1 = new Node(5);
        tree2_1.left = new Node(3);
        tree2_1.right = new Node(4);
        tree2_1.left.left = new Node(1);
        tree2_1.right.left = new Node(2);

        System.out.println(checkIsAnagrams(tree1_1, tree2_1));

        // Example 2
        Node tree1_2 = new Node(5);
        tree1_2.left = new Node(7);
        tree1_2.right = new Node(8);
        tree1_2.left.left = new Node(9);

        Node tree2_2 = new Node(5);
        tree2_2.left = new Node(7);
        tree2_2.right = new Node(8);
        tree2_2.left.left = new Node(1);
        tree2_2.right.left = new Node(2);

        System.out.println(checkIsAnagrams(tree1_2, tree2_2));
    }
}
true
false

קוד C ++ כדי לבדוק אם כל הרמות של שני עץ בינארי הן אנגרמות או לא

#include<bits/stdc++.h> 
using namespace std; 

// class representing node of a binary tree
class Node {
    public:
    int data;
    Node *left;
    Node *right;
    
    Node(int d) {
        data = d;
        left = right = NULL;
    }
};

// function to create a new node with given data
Node* newNode(int data) {
    Node *node = new Node(data);
    return node;
}

bool checkIsAnagrams(Node *tree1, Node *tree2) {
    // create two queues
    queue<Node *> q1;
    queue<Node *> q2;
    // add root of tree1 to q1
    q1.push(tree1);
    // add root of tree2 to q2
    q2.push(tree2);
    
    // while either of q1 or q2 is not empty
    while (!q1.empty() || !q2.empty()) {
        // create a hash map to store freq of elements of a level
        unordered_map<int, int> freq;
        
        // traverse this level of tree1
        int size1 = q1.size();
        for (int i = 0; i < size1; i++) {
            // remove a node from queue
            Node *curr = q1.front();
            q1.pop();
            
            // add the element to hash map
            auto itr = freq.find(curr->data);
            if (itr != freq.end()) {
                itr->second++;
            } else {
                freq.insert(make_pair(curr->data, 1));
            }
            
            // add curr's children to queue
            if (curr->left != NULL)
                q1.push(curr->left);
            if (curr->right != NULL)
                q1.push(curr->right);
        }
        
        // traverse this level of tree2
        int size2 = q2.size();
        for (int i = 0; i < size2; i++) {
            // remove a node from q2
            Node *curr = q2.front();
            q2.pop();
    
            // decrease the frequency of this element in hash map
            auto itr = freq.find(curr->data);
            if (itr != freq.end()) {
                itr->second--;
                if (itr->second == 0) {
                    freq.erase(itr);
                }
            } else {
                return false;
            }
            
            // add curr's children to queue
            if (curr->left != NULL)
                q2.push(curr->left);
            if (curr->right != NULL)
                q2.push(curr->right);
        }
        
        // if there is an element in the hash map
        // the two tree's current levels are not anagrams
        if (freq.size() != 0)
            return false;
    }
    
    // all the levels are anagrams, return true
    return true;
}

int main() {
    // Example 1
    Node *tree1_1 = newNode(5);
    tree1_1->left = newNode(4);
    tree1_1->right = newNode(3);
    tree1_1->left->left = newNode(2);
    tree1_1->left->right = newNode(1);

    Node *tree2_1 = new Node(5);
    tree2_1->left = newNode(3);
    tree2_1->right = newNode(4);
    tree2_1->left->left = newNode(1);
    tree2_1->right->left = newNode(2);

    if (checkIsAnagrams(tree1_1, tree2_1)) {
        cout<<"true"<<endl;
    } else {
        cout<<"false"<<endl;
    }

    // Example 2
    Node *tree1_2 = newNode(5);
    tree1_2->left = newNode(7);
    tree1_2->right = newNode(8);
    tree1_2->left->left = newNode(9);

    Node *tree2_2 = newNode(5);
    tree2_2->left = newNode(7);
    tree2_2->right = newNode(8);
    tree2_2->left->left = newNode(1);
    tree2_2->right->left = newNode(2);

    if (checkIsAnagrams(tree1_2, tree2_2)) {
        cout<<"true"<<endl;
    } else {
        cout<<"false"<<endl;
    }   
    
    return 0;
}
true
false

ניתוח מורכבות

כשעברנו את שני העצים בדיוק פעם אחת והשתמשנו בשני תורים לחציית סדר ברמה, כך

מורכבות זמן = O (n + m)
מורכבות בחלל = O (n + m)
כאשר n הוא מספר הצמתים בעץ 1 ו- m הוא מספר הצמתים בעץ 2.