Skip to content

Commit 1551e7f

Browse files
committed
the largest Common subtree
1 parent 2eec824 commit 1551e7f

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed

tree/LargestCommonSubtrees.java

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package Algorithms.tree;
2+
3+
import java.util.*;
4+
5+
6+
public class LargestCommonSubtrees {
7+
/*
8+
* Function: Find all the common subtrees root that have most number
9+
*/
10+
private static class TreeNode {
11+
int val;
12+
ArrayList<TreeNode> subNodes;
13+
public TreeNode(int val, ArrayList<TreeNode> subNodes) {
14+
this.val = val;
15+
this.subNodes = subNodes;
16+
}
17+
}
18+
19+
public static void main(String[] args) {
20+
/*
21+
* 1
22+
*
23+
* / \ \
24+
* 2 3 4
25+
* / \ / \
26+
* 5 6 8 9
27+
* \ \
28+
* 7 10
29+
* */
30+
TreeNode r1 = new TreeNode(1, new ArrayList<TreeNode>());
31+
TreeNode r2 = new TreeNode(2, new ArrayList<TreeNode>());
32+
TreeNode r3 = new TreeNode(3, new ArrayList<TreeNode>());
33+
TreeNode r4 = new TreeNode(4, new ArrayList<TreeNode>());
34+
TreeNode r5 = new TreeNode(5, new ArrayList<TreeNode>());
35+
TreeNode r6 = new TreeNode(6, new ArrayList<TreeNode>());
36+
TreeNode r7 = new TreeNode(7, new ArrayList<TreeNode>());
37+
TreeNode r8 = new TreeNode(8, new ArrayList<TreeNode>());
38+
TreeNode r9 = new TreeNode(9, new ArrayList<TreeNode>());
39+
TreeNode r10 = new TreeNode(10, new ArrayList<TreeNode>());
40+
41+
r1.subNodes.add(r2);
42+
r1.subNodes.add(r3);
43+
r1.subNodes.add(r4);
44+
45+
r2.subNodes.add(r5);
46+
r2.subNodes.add(r6);
47+
48+
r6.subNodes.add(r7);
49+
50+
r4.subNodes.add(r8);
51+
r4.subNodes.add(r9);
52+
53+
r9.subNodes.add(r10);
54+
55+
ArrayList<ArrayList<TreeNode>> ret = largestCommonSubtrees(r1);
56+
for (ArrayList<TreeNode> arrayl: ret) {
57+
for (TreeNode t: arrayl) {
58+
System.out.println(t.val);
59+
}
60+
}
61+
62+
}
63+
64+
public static ArrayList<ArrayList<TreeNode>> largestCommonSubtrees(TreeNode root) {
65+
if (root == null) {
66+
return null;
67+
}
68+
69+
ArrayList<ArrayList<TreeNode>> ret = new ArrayList<ArrayList<TreeNode>>();
70+
71+
// store all the tree nodes to a arrayList.
72+
ArrayList<TreeNode> nodes = new ArrayList<TreeNode>();
73+
traversalTree(root, nodes);
74+
75+
int maxNum = 0;
76+
77+
HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
78+
79+
TreeNode r1 = null;
80+
TreeNode r2 = null;
81+
82+
83+
// compare all the nodes.
84+
int size = nodes.size();
85+
for (int i = 0; i < size; i++) {
86+
for (int j = 0; j < size; j++) {
87+
if (i == j) {
88+
continue;
89+
}
90+
int num = compareTree(nodes.get(i), nodes.get(j), hash);
91+
if (num > maxNum) {
92+
ArrayList<TreeNode> iden = new ArrayList<TreeNode>();
93+
iden.add(nodes.get(i));
94+
iden.add(nodes.get(j));
95+
96+
ret.add(iden);
97+
r1 = nodes.get(i);
98+
r2 = nodes.get(j);
99+
}
100+
}
101+
}
102+
103+
ArrayList<ArrayList<TreeNode>> retNew = new ArrayList<ArrayList<TreeNode>>();
104+
retNew.add(new ArrayList<TreeNode>());
105+
retNew.get(0).add(r1);
106+
retNew.get(0).add(r2);
107+
return retNew;
108+
}
109+
110+
111+
// compare two tree, if same, return the number of leafs. if no, return -1;
112+
public static int compareTree(TreeNode r1, TreeNode r2, HashMap<Integer, Integer> hash) {
113+
if (r1 == null && r2 == null) {
114+
return 0;
115+
}
116+
117+
if (r1 == null || r2 == null) {
118+
return -1;
119+
}
120+
121+
// the number of subtrees should be same.
122+
if (r1.subNodes.size() != r2.subNodes.size()) {
123+
return -1;
124+
}
125+
126+
int num = 1; // the root itself.
127+
128+
for (int i = 0; i < r1.subNodes.size(); i++) {
129+
// get the subNode of r1.
130+
TreeNode subNode1 = r1.subNodes.get(i);
131+
TreeNode subNode2 = r2.subNodes.get(i);
132+
133+
int HashCode = hashCode(subNode1, subNode2);
134+
135+
Integer numNode = hash.get(HashCode);
136+
if (numNode == null) {
137+
numNode = compareTree(subNode1, subNode2, hash);
138+
}
139+
140+
if (numNode == -1) {
141+
// not the same, should return;
142+
num = -1;
143+
break;
144+
} else {
145+
num += numNode;
146+
continue;
147+
}
148+
}
149+
150+
int hashCodeRoot = hashCode(r1, r2);
151+
hash.put(hashCodeRoot, num);
152+
153+
return num;
154+
}
155+
156+
public static int hashCode(TreeNode r1, TreeNode r2) {
157+
int hash = r1.hashCode() * 31 + r2.hashCode();
158+
return hash;
159+
}
160+
161+
public static void traversalTree(TreeNode root, ArrayList<TreeNode> ret) {
162+
if (root == null) {
163+
return;
164+
}
165+
166+
ret.add(root);
167+
168+
// add all the sub nodes.
169+
if (root.subNodes != null) {
170+
for(TreeNode t: root.subNodes) {
171+
traversalTree(t, ret);
172+
}
173+
}
174+
}
175+
176+
177+
}

0 commit comments

Comments
 (0)