给定一棵二叉树,找出所有重复的子树。对于每个重复的子树,我们只需要返回其中任何一个的根节点。如果两棵树具有相同的结构和相同的节点值,则它们是重复的。
例子:
Input :
1
/ \
2 3
/ / \
4 2 4
/
4
Output :
2
/ and 4
4
Explanation: Above Trees are two duplicate subtrees.
Therefore, you need to return above trees root in the
form of a list.
这个想法是使用散列。我们将子树的中序遍历存储在哈希中。由于简单的中序遍历不能唯一地标识一棵树,我们使用像'(‘和’)’这样的符号来表示NULL节点。
我们将 C++ 中的无序映射作为参数传递给辅助函数,该函数递归计算中序字符串并增加其在映射中的计数。如果任何字符串被重复,那么它将意味着以该节点为根的子树的重复,因此将该节点推入最终结果并返回这些节点的向量。
C++
// C++ program to find averages of all levels
// in a binary tree.
#include
using namespace std;
/* A binary tree node has data, pointer to
left child and a pointer to right child */
struct Node {
int data;
struct Node* left, *right;
};
string inorder(Node* node, unordered_map& m)
{
if (!node)
return "";
string str = "(";
str += inorder(node->left, m);
str += to_string(node->data);
str += inorder(node->right, m);
str += ")";
// Subtree already present (Note that we use
// unordered_map instead of unordered_set
// because we want to print multiple duplicates
// only once, consider example of 4 in above
// subtree, it should be printed only once.
if (m[str] == 1)
cout << node->data << " ";
m[str]++;
return str;
}
// Wrapper over inorder()
void printAllDups(Node* root)
{
unordered_map m;
inorder(root, m);
}
/* Helper function that allocates a
new node with the given data and
NULL left and right pointers. */
Node* newNode(int data)
{
Node* temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
// Driver code
int main()
{
Node* root = NULL;
root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->right->left = newNode(2);
root->right->left->left = newNode(4);
root->right->right = newNode(4);
printAllDups(root);
return 0;
}
Java
// A java program to find all duplicate subtrees
// in a binary tree.
import java.util.HashMap;
public class Duplicate_subtress {
/* A binary tree node has data, pointer to
left child and a pointer to right child */
static HashMap m;
static class Node {
int data;
Node left;
Node right;
Node(int data){
this.data = data;
left = null;
right = null;
}
}
static String inorder(Node node)
{
if (node == null)
return "";
String str = "(";
str += inorder(node.left);
str += Integer.toString(node.data);
str += inorder(node.right);
str += ")";
// Subtree already present (Note that we use
// HashMap instead of HashSet
// because we want to print multiple duplicates
// only once, consider example of 4 in above
// subtree, it should be printed only once.
if (m.get(str) != null && m.get(str)==1 )
System.out.print( node.data + " ");
if (m.containsKey(str))
m.put(str, m.get(str) + 1);
else
m.put(str, 1);
return str;
}
// Wrapper over inorder()
static void printAllDups(Node root)
{
m = new HashMap<>();
inorder(root);
}
// Driver code
public static void main(String args[])
{
Node root = null;
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.right.left = new Node(2);
root.right.left.left = new Node(4);
root.right.right = new Node(4);
printAllDups(root);
}
}
// This code is contributed by Sumit Ghosh
Python3
# Python3 program to find averages of
# all levels in a binary tree.
# Helper function that allocates a
# new node with the given data and
# None left and right pointers.
class newNode:
def __init__(self, data):
self.data = data
self.left = self.right = None
def inorder(node, m):
if (not node):
return ""
Str = "("
Str += inorder(node.left, m)
Str += str(node.data)
Str += inorder(node.right, m)
Str += ")"
# Subtree already present (Note that
# we use unordered_map instead of
# unordered_set because we want to print
# multiple duplicates only once, consider
# example of 4 in above subtree, it
# should be printed only once.
if (Str in m and m[Str] == 1):
print(node.data, end = " ")
if Str in m:
m[Str] += 1
else:
m[Str] = 1
return Str
# Wrapper over inorder()
def printAllDups(root):
m = {}
inorder(root, m)
# Driver code
if __name__ == '__main__':
root = None
root = newNode(1)
root.left = newNode(2)
root.right = newNode(3)
root.left.left = newNode(4)
root.right.left = newNode(2)
root.right.left.left = newNode(4)
root.right.right = newNode(4)
printAllDups(root)
# This code is contributed by PranchalK
C#
// A C# program to find all duplicate subtrees
// in a binary tree.
using System;
using System.Collections.Generic;
class GFG
{
/* A binary tree node has data, pointer to
left child and a pointer to right child */
static Dictionary m = new Dictionary();
public class Node
{
public int data;
public Node left;
public Node right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
static String inorder(Node node)
{
if (node == null)
return "";
String str = "(";
str += inorder(node.left);
str += (node.data).ToString();
str += inorder(node.right);
str += ")";
// Subtree already present (Note that we use
// HashMap instead of HashSet
// because we want to print multiple duplicates
// only once, consider example of 4 in above
// subtree, it should be printed only once.
if (m.ContainsKey(str) && m[str] == 1 )
Console.Write(node.data + " ");
if (m.ContainsKey(str))
m[str] = m[str] + 1;
else
m.Add(str, 1);
return str;
}
// Wrapper over inorder()
static void printAllDups(Node root)
{
m = new Dictionary();
inorder(root);
}
// Driver code
public static void Main(String []args)
{
Node root = null;
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.right.left = new Node(2);
root.right.left.left = new Node(4);
root.right.right = new Node(4);
printAllDups(root);
}
}
// This code is contributed by Princi Singh
Javascript
输出:
4 2
时间复杂度: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。