📜  检查两棵树的所有级别是否都是字谜

📅  最后修改于: 2022-05-13 01:57:00.821000             🧑  作者: Mango

检查两棵树的所有级别是否都是字谜

给定两个二叉树,我们必须检查它们的每个级别是否是彼此的字谜。
例子:

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。



Tree 1:
Level 0 : 1
Level 1 : 3, 2
Level 2 : 5, 4

Tree 2:
Level 0 : 1
Level 1 : 2, 3
Level 2 : 4, 5

我们可以清楚地看到上面两个二叉树的所有级别都是彼此的字谜,因此返回true。

朴素的方法:以下是执行此操作的朴素方法的分步说明:

  1. 为树的层序遍历编写递归程序。
  2. 一一遍历两棵树的每一层,并将遍历结果存储在 2 个不同的向量中,每个向量一个。
  3. 对两个向量进行排序并针对每个级别迭代比较它们,如果每个级别的它们都相同,则返回 true 否则返回 false。

时间复杂度: O(n^2),其中 n 是节点数。
有效的方法:
这个想法是基于下面的文章。
逐行打印级别顺序遍历|设置 1
我们一层一层地同时遍历两棵树。我们将每个级别的两棵树都存储在向量(或数组)中。为了检查两个向量是否是变位词,我们对两者进行排序然后比较。
时间复杂度: O(nlogn) ,其中 n 是节点数。

C++
/* Iterative program to check if two trees are level
   by level anagram. */
#include 
using namespace std;
 
// A Binary Tree Node
struct Node
{
    struct Node *left, *right;
    int data;
};
 
// Returns true if trees with root1 and root2
// are level by level anagram, else returns false.
bool areAnagrams(Node *root1, Node *root2)
{
    // Base Cases
    if (root1 == NULL && root2 == NULL)
        return true;
    if (root1 == NULL || root2 == NULL)
        return false;
 
    // start level order traversal of two trees
    // using two queues.
    queue q1, q2;
    q1.push(root1);
    q2.push(root2);
 
    while (1)
    {
        // n1 (queue size) indicates number of Nodes
        // at current level in first tree and n2 indicates
        // number of nodes in current level of second tree.
        int n1 = q1.size(), n2 = q2.size();
 
        // If n1 and n2 are different
        if (n1 != n2)
            return false;
 
        // If level order traversal is over 
        if (n1 == 0)
            break;
 
        // Dequeue all Nodes of current level and
        // Enqueue all Nodes of next level
        vector curr_level1, curr_level2;
        while (n1 > 0)
        {
            Node *node1 = q1.front();
            q1.pop();
            if (node1->left != NULL)
                q1.push(node1->left);
            if (node1->right != NULL)
                q1.push(node1->right);
            n1--;
 
            Node *node2 = q2.front();
            q2.pop();
            if (node2->left != NULL)
                q2.push(node2->left);
            if (node2->right != NULL)
                q2.push(node2->right);
 
            curr_level1.push_back(node1->data);
            curr_level2.push_back(node2->data);
        }
 
        // Check if nodes of current levels are
        // anagrams or not.
        sort(curr_level1.begin(), curr_level1.end());
        sort(curr_level2.begin(), curr_level2.end());
        if (curr_level1 != curr_level2)
            return false;
    }
 
    return true;
}
 
// Utility function to create a new tree Node
Node* newNode(int data)
{
    Node *temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
// Driver program to test above functions
int main()
{
    // Constructing both the trees.
    struct Node* root1 = newNode(1);
    root1->left = newNode(3);
    root1->right = newNode(2);
    root1->right->left = newNode(5);
    root1->right->right = newNode(4);
 
    struct Node* root2 = newNode(1);
    root2->left = newNode(2);
    root2->right = newNode(3);
    root2->left->left = newNode(4);
    root2->left->right = newNode(5);
 
    areAnagrams(root1, root2)? cout << "Yes" : cout << "No";
    return 0;
}


Java
/* Iterative program to check if two trees
are level by level anagram. */
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
 
 
public class GFG
{                                
    // A Binary Tree Node
    static class Node
    {
        Node left, right;
        int data;
        Node(int data){
            this.data = data;
            left = null;
            right = null;
        }
    }
      
    // Returns true if trees with root1 and root2
    // are level by level anagram, else returns false.
    static boolean areAnagrams(Node root1, Node root2)
    {
        // Base Cases
        if (root1 == null && root2 == null)
            return true;
        if (root1 == null || root2 == null)
            return false;
      
        // start level order traversal of two trees
        // using two queues.
        Queue q1 = new LinkedList();
        Queue q2 = new LinkedList();
        q1.add(root1);
        q2.add(root2);
      
        while (true)
        {
            // n1 (queue size) indicates number of
            // Nodes at current level in first tree
            // and n2 indicates number of nodes in
            // current level of second tree.
            int n1 = q1.size(), n2 = q2.size();
      
            // If n1 and n2 are different
            if (n1 != n2)
                return false;
      
            // If level order traversal is over 
            if (n1 == 0)
                break;
      
            // Dequeue all Nodes of current level and
            // Enqueue all Nodes of next level
            ArrayList curr_level1 = new
                                          ArrayList<>();
            ArrayList curr_level2 = new
                                          ArrayList<>();
            while (n1 > 0)
            {
                Node node1 = q1.peek();
                q1.remove();
                if (node1.left != null)
                    q1.add(node1.left);
                if (node1.right != null)
                    q1.add(node1.right);
                n1--;
      
                Node node2 = q2.peek();
                q2.remove();
                if (node2.left != null)
                    q2.add(node2.left);
                if (node2.right != null)
                    q2.add(node2.right);
      
                curr_level1.add(node1.data);
                curr_level2.add(node2.data);
            }
      
            // Check if nodes of current levels are
            // anagrams or not.
            Collections.sort(curr_level1);
            Collections.sort(curr_level2);
             
            if (!curr_level1.equals(curr_level2))
                return false;
        }
      
        return true;
    }
     
    // Driver program to test above functions
    public static void main(String args[])
    {
        // Constructing both the trees.
        Node root1 = new Node(1);
        root1.left = new Node(3);
        root1.right = new Node(2);
        root1.right.left = new Node(5);
        root1.right.right = new Node(4);
      
        Node root2 = new Node(1);
        root2.left = new Node(2);
        root2.right = new Node(3);
        root2.left.left = new Node(4);
        root2.left.right = new Node(5);
      
         
        System.out.println(areAnagrams(root1, root2)?
                             "Yes" : "No");
    }
}
// This code is contributed by Sumit Ghosh


Python3
# Iterative program to check if two
# trees are level by level anagram
 
# A Binary Tree Node
# Utility function to create a
# new tree Node
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# Returns true if trees with root1
# and root2 are level by level
# anagram, else returns false.
def areAnagrams(root1, root2) :
 
    # Base Cases
    if (root1 == None and root2 == None) :
        return True
    if (root1 == None or root2 == None) :
        return False
 
    # start level order traversal of
    # two trees using two queues.
    q1 = []
    q2 = []
    q1.append(root1)
    q2.append(root2)
 
    while (1) :
     
        # n1 (queue size) indicates number
        # of Nodes at current level in first
        # tree and n2 indicates number of nodes
        # in current level of second tree.
        n1 = len(q1)
        n2 = len(q2)
 
        # If n1 and n2 are different
        if (n1 != n2):
            return False
 
        # If level order traversal is over
        if (n1 == 0):
            break
 
        # Dequeue all Nodes of current level
        # and Enqueue all Nodes of next level
        curr_level1 = []
        curr_level2 = []
        while (n1 > 0):
            node1 = q1[0]
            q1.pop(0)
            if (node1.left != None) :
                q1.append(node1.left)
            if (node1.right != None) :
                q1.append(node1.right)
            n1 -= 1
 
            node2 = q2[0]
            q2.pop(0)
            if (node2.left != None) :
                q2.append(node2.left)
            if (node2.right != None) :
                q2.append(node2.right)
 
            curr_level1.append(node1.data)
            curr_level2.append(node2.data)
             
        # Check if nodes of current levels
        # are anagrams or not.
        curr_level1.sort()
        curr_level2.sort()
        if (curr_level1 != curr_level2) :
            return False
     
    return True
 
# Driver Code
if __name__ == '__main__':
     
    # Constructing both the trees.
    root1 = newNode(1)
    root1.left = newNode(3)
    root1.right = newNode(2)
    root1.right.left = newNode(5)
    root1.right.right = newNode(4)
 
    root2 = newNode(1)
    root2.left = newNode(2)
    root2.right = newNode(3)
    root2.left.left = newNode(4)
    root2.left.right = newNode(5)
    if areAnagrams(root1, root2):
        print("Yes") 
    else:
        print("No")
 
# This code is contributed
# by SHUBHAMSINGH10


C#
/* Iterative program to check if two trees
are level by level anagram. */
using System;
using System.Collections.Generic;
 
class GFG
{                            
    // A Binary Tree Node
    public class Node
    {
        public Node left, right;
        public int data;
        public Node(int data)
        {
            this.data = data;
            left = null;
            right = null;
        }
    }
     
    // Returns true if trees with root1
    // and root2 are level by level anagram,
    // else returns false.
    static Boolean areAnagrams(Node root1,
                               Node root2)
    {
        // Base Cases
        if (root1 == null && root2 == null)
            return true;
        if (root1 == null || root2 == null)
            return false;
     
        // start level order traversal of two trees
        // using two queues.
        Queue q1 = new Queue();
        Queue q2 = new Queue();
        q1.Enqueue(root1);
        q2.Enqueue(root2);
     
        while (true)
        {
            // n1 (queue size) indicates number of
            // Nodes at current level in first tree
            // and n2 indicates number of nodes in
            // current level of second tree.
            int n1 = q1.Count, n2 = q2.Count;
     
            // If n1 and n2 are different
            if (n1 != n2)
                return false;
     
            // If level order traversal is over
            if (n1 == 0)
                break;
     
            // Dequeue all Nodes of current level and
            // Enqueue all Nodes of next level
            List curr_level1 = new List();
            List curr_level2 = new List();
            while (n1 > 0)
            {
                Node node1 = q1.Peek();
                q1.Dequeue();
                if (node1.left != null)
                    q1.Enqueue(node1.left);
                if (node1.right != null)
                    q1.Enqueue(node1.right);
                n1--;
     
                Node node2 = q2.Peek();
                q2.Dequeue();
                if (node2.left != null)
                    q2.Enqueue(node2.left);
                if (node2.right != null)
                    q2.Enqueue(node2.right);
     
                curr_level1.Add(node1.data);
                curr_level2.Add(node2.data);
            }
     
            // Check if nodes of current levels are
            // anagrams or not.
            curr_level1.Sort();
            curr_level2.Sort();
             
            for(int i = 0;
                    i < curr_level1.Count; i++)
            if(curr_level1[i] != curr_level2[i])
                return false;
        }
        return true;
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        // Constructing both the trees.
        Node root1 = new Node(1);
        root1.left = new Node(3);
        root1.right = new Node(2);
        root1.right.left = new Node(5);
        root1.right.right = new Node(4);
     
        Node root2 = new Node(1);
        root2.left = new Node(2);
        root2.right = new Node(3);
        root2.left.left = new Node(4);
        root2.left.right = new Node(5);
     
         
        Console.WriteLine(areAnagrams(root1,
                                      root2) ?
                                       "Yes" : "No");
    }
}
 
// This code is contributed by Arnab Kundu


输出:

Yes

注意:在上面的程序中,我们直接使用不等于函数'!='比较存储树的每一层的向量,它首先根据向量的大小然后根据它们的内容比较向量,从而节省了我们的迭代比较向量的工作。