Problem#
Given the roots of two binary trees p
and q
, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.
Example#
Input: Two binary Search Trees
Check if Two Binary Tree’s are Identical
Example 1:
1
2
3
4
5
6
7
8
9
|
p =
1
/ \
2 3
q =
1
/ \
2 3
|
1
2
|
Input: p = [1,2,3], q = [1,2,3]
Output: true
|
Solution#
Method 1 - Recursive#
Algorithm#
- Recursive Traversal: Begin by traversing both trees simultaneously from their roots.
- Match Check: If either root is null or their data doesn’t match, return
false
(structural or value mismatch).
- Subtree Verification: Recursively check if
p.left
is a subtree of q.left
and p.right
is a subtree of q.right
.
- Completion Consistency: If one tree finishes traversing (null) while the other has nodes, return
false
(structural difference).
- Match Confirmation: If both trees reach the end simultaneously (both null), return
true
(trees match).
Code#
1
2
3
4
5
6
7
8
9
10
11
12
|
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
return p.val == q.val &&
isSameTree(p.left, q.left) &&
isSameTree(p.right, q.right);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
pub fn is_same_tree(p: Option<Rc<RefCell<TreeNode>>>, q: Option<Rc<RefCell<TreeNode>>>) -> bool {
match (p, q) {
(None, None) => true,
(Some(p), Some(q)) => {
let p = p.borrow();
let q = q.borrow();
p.val == q.val
&& Self::is_same_tree(p.left.clone(), q.left.clone())
&& Self::is_same_tree(p.right.clone(), q.right.clone())
}
_ => false,
}
}
}
|
1
2
|
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
|
1
2
3
|
pub fn is_same_tree(p: Option<Rc<RefCell<TreeNode>>>, q: Option<Rc<RefCell<TreeNode>>>) -> bool {
p == q
}
|
Method 2 - Iterative using Level Order Traversal#
Code#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
func isSameTree(p *TreeNode, q *TreeNode) bool {
type Pair struct {
p, q *TreeNode
}
var queue []Pair
queue = append(traverse, Pair{p, q})
for len(traverse) > 0 {
pair := queue[len(traverse) - 1]
traverse = queue[:len(traverse) - 1]
if pair.p != nil && pair.q != nil && pair.p.Val == pair.q.Val {
traverse = append(traverse, Pair{pair.p.Left, pair.q.Left})
traverse = append(traverse, Pair{pair.p.Right, pair.q.Right})
} else if pair.p != nil || pair.q != nil {
return false
}
}
return true
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public boolean isSameTree(TreeNode p, TreeNode q) {
Queue<TreeNode> queue1 = new LinkedList<>();
Queue<TreeNode> queue2 = new LinkedList<>();
queue1.offer(p);
queue2.offer(q);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
TreeNode node1 = queue1.poll();
TreeNode node2 = queue2.poll();
if (node1 == null && node2 == null) {
continue;
}
if (node1 == null || node2 == null || node1.val != node2.val) {
return false;
}
queue1.offer(node1.left);
queue1.offer(node1.right);
queue2.offer(node2.left);
queue2.offer(node2.right);
}
return queue1.isEmpty() && queue2.isEmpty();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
pub fn is_same_tree(p: Option<Rc<RefCell<TreeNode>>>, q: Option<Rc<RefCell<TreeNode>>>) -> bool {
let mut queue = Vec::new();
queue.push((p, q));
while let Some((mut p, mut q)) = queue.pop() {
if p.is_none() != q.is_none() {
return false
} else if let (Some(p), Some(q)) = (p.take(), q.take()) {
let (mut p, mut q) = (p.borrow_mut(), q.borrow_mut());
if p.val != q.val {
return false
}
queue.push((p.left.take(), q.left.take()));
queue.push((p.right.take(), q.right.take()));
}
}
true
}
}
|
Method 3 - Iterative using DFS#
Code#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public boolean isSameTree(TreeNode p, TreeNode q) {
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(p);
stack2.push(q);
while (!stack1.isEmpty() && !stack2.isEmpty()) {
TreeNode node1 = stack1.pop();
TreeNode node2 = stack2.pop();
if (node1 == null && node2 == null) {
continue;
} else if (node1 == null || node2 == null || node1.val != node2.val) {
return false;
}
stack1.push(node1.left);
stack2.push(node2.left);
stack1.push(node1.right);
stack2.push(node2.right);
}
return stack1.isEmpty() && stack2.isEmpty();
}
|