Problem
Given the root
of a binary tree with unique values and the values of two different nodes of the tree x
and y
, return true
if the nodes corresponding to the values x
and y
in the tree are cousins, or false
otherwise.
Definition
Examples
Example 1:
1
/ \
2 3
/
4
Input: root = [1,2,3,4], x = 4, y = 3
Output: false
Example 2:
1
/ \
2 3
/
4
Input: root = [1,2,3,null,4], x = 2, y = 3
Output: false
Example 3:
1
/ \
2 3
\ \
4 5
Input: root = [1,2,3,null,4,null,5], x = 5, y = 4
Output: true
More examples
graph TD; 1 --> 2 & 3 2 --> 4 & 5 3 --> 6 & 7 4 --> 8 & 9 6 --> 12 & 13
x = 1, y = 2, false
x = 2, y = 3, false
x = 3, y = 4, false
x = 4, y = 6, true
x = 8, y = 12, true
Similar Problem
Cousins in Binary Tree 2 Problem
Solution
Method 1 - Level order traversal
To determine if two nodes are cousins, we need to know:
- The depth of each node.
- The parent of each node.
Using level-order traversal (BFS) is suitable as it allows us to naturally track the depth of nodes. During the traversal, we can record the depth and parent of each node. With this information, we can later check the conditions for nodes x
and y
to be cousins.
Here is the approach:
- Level-Order Traversal (BFS):
- Use a queue to perform BFS. Track the parent and depth of each node as we visit them.
- Initialize the queue with the root node and depth
0
. - For each node, record its children with the incremented depth and the current node as their parent.
- Check Conditions for Cousins:
- After the traversal, check if nodes
x
andy
have the same depth but different parents.
- After the traversal, check if nodes
Code
Java
public class Solution {
public boolean isCousins(TreeNode root, int x, int y) {
if (root == null) return false;
Map<Integer, Integer> depth = new HashMap<>();
Map<Integer, TreeNode> parent = new HashMap<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
depth.put(root.val, 0);
parent.put(root.val, null);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
depth.put(node.left.val, depth.get(node.val) + 1);
parent.put(node.left.val, node);
}
if (node.right != null) {
queue.offer(node.right);
depth.put(node.right.val, depth.get(node.val) + 1);
parent.put(node.right.val, node);
}
}
return depth.get(x) == depth.get(y) && parent.get(x) != parent.get(y);
}
}
Python
class Solution:
def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
if not root:
return False
queue = deque([root])
depth = {root.val: 0}
parent = {root.val: None}
while queue:
node = queue.popleft()
if node.left:
queue.append(node.left)
depth[node.left.val] = depth[node.val] + 1
parent[node.left.val] = node
if node.right:
queue.append(node.right)
depth[node.right.val] = depth[node.val] + 1
parent[node.right.val] = node
return (depth[x] == depth[y]) and (parent[x] != parent[y])
Method 2 - DFS with Height and Parent Check in 2 Iterations
Check the height of both the nodes, if heights are different then return false. Check if both the nodes has the same parent, if yes then return false. else return true.
Code
Java
public boolean areCousins(Node root, int x, int y) {
if (getHeight(root, x, 1) != getHeight(root, y, 1)) {
return false;
}
if (sameParents(root, x, y) == false) {
return true;
}
return false;
}
public int getHeight(Node root, int x, int height) {
if (root == null) {
return 0;
}
if (root.val == x) {
return height;
}
int level = getHeight(root.left, x, height + 1);
if (level != 0) {
return level;
}
return getHeight(root.right, x, height + 1);
}
public boolean sameParents(Node root, int x, int y) {
if (root == null) {
return false;
}
return ((root.left.val == x && root.right.val == y) ||
(root.left.val == y && root.right.val == x) ||
sameParents(root.left, x, y) || sameParents(root.right, x, y));
}
Method 3 - DFS with Height and Parent Check in 1 Iteration
Code
Java
static class NodeComparisonResult {
public int parent1;
public int depth1;
public int parent2;
public int depth2;
}
public boolean isCousins(TreeNode root, int x, int y) {
NodeComparisonResult res = new NodeComparisonResult();
inorder(root.left, x, y, 0, root, res);
inorder(root.right, x, y, 0, root, res);
if (res.parent1 != res.parent2 && res.depth1 == res.depth2) {
return true;
}
return false;
}
public void inorder(TreeNode node, int x, int y, int depth, TreeNode parent, NodeComparisonResult res) {
if (node == null)
return;
depth = depth + 1;
inorder(node.left, x, y, depth, node, res);
if (node.val == x) {
res.parent1 = parent.val;
res.depth1 = depth;
return;
} else if (node.val == y) {
res.parent2 = parent.val;
res.depth2 = depth;
return;
}
inorder(node.right, x, y, depth, node, res);
}