
Problem Statement
In this task, we are given the root of a binary tree where each node has unique values, along with two specific values x
and y
representing different nodes in the tree. We must determine if the nodes corresponding to these values are "cousins". For clarification, cousins in a binary tree are defined as nodes that are at the same depth (or level) but do not share the same parent. The task involves checking the relationship between the nodes corresponding to x
and y
according to these definitions and returning true
if they are cousins, otherwise returning false
.
Examples
Example 1
Input:
root = [1,2,3,4], x = 4, y = 3
Output:
false
Example 2
Input:
root = [1,2,3,null,4,null,5], x = 5, y = 4
Output:
true
Example 3
Input:
root = [1,2,3,null,4], x = 2, y = 3
Output:
false
Constraints
- The number of nodes in the tree is in the range
[2, 100]
. 1 <= Node.val <= 100
- Each node has a unique value.
x != y
x
andy
are exist in the tree.
Approach and Intuition
To solve the problem, we need to determine if the nodes
x
andy
are at the same depth yet have different parents. This leads us to using a breadth-first search (BFS), which provides a systematic method for exploring the tree level by level.Initiate a queue that will include nodes alongside their corresponding depth and their parent information. Start with the root node having depth
0
and no parent (null
).Process the nodes in the queue:
- For each node, check its children.
- If a child is either
x
ory
, store its depth and its parent. - Put the child into the queue with incremented depth and current node as the parent.
After populating the parent and depth information for both
x
andy
(or determining that one/both are absent in the tree), compare their depths and parents:- Cousins are identified by having the same depth but different parents.
Given the constraints:
- Since each node value must be unique, there's no ambiguity in node identification.
- The tree size range ([2, 100]) ensures our BFS approach remains efficient.
- Verification includes checking if both
x
andy
actually exist in the tree as given by the constraintx and y are exist in the tree
.
Using the examples provided:
- The first example, with nodes
[1,2,3,4]
andx = 4, y = 3
, showsx
andy
at different depths, resulting infalse
. - In the second example, in the tree
[1,2,3,null,4,null,5]
,x = 5
andy = 4
are at the same depth and do not share the same parent, thustrue
. - The third example shows a sibling relationship (
x = 2
andy = 3
share the same parent), which mean they are not cousins, hencefalse
.
- The first example, with nodes
Through following this approach and set of checks, one can effectively and accurately determine cousin relationships in a binary tree as defined.
Solutions
- Java
- Python
class Solution {
public boolean checkCousins(TreeNode root, int x, int y) {
// Use queue for level order traversal
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
boolean isSibling = false;
boolean isCousin = false;
int levelSize = q.size();
for (int i = 0; i < levelSize; ++i) {
TreeNode current = q.poll();
if (current == null) isSibling = false; // Reset sibling status at each boundary.
else {
if (current.val == x || current.val == y) {
if (!isCousin) {
isSibling = isCousin = true;
} else {
return !isSibling;
}
}
if (current.left != null) q.add(current.left);
if (current.right != null) q.add(current.right);
q.add(null); // Define a boundary for siblings.
}
}
if (isCousin) return false; // Found only one node of interest.
}
return false;
}
}
This Java solution checks whether two nodes in a binary tree are cousins. Cousins are nodes that are on the same level but have different parents. The method checkCousins
utilizes level order traversal (using breadth-first search) to explore the tree and compare nodes.
- Start by initializing a queue and adding the root node to it.
- Continue with a loop that processes nodes until the queue is empty.
- At each level of the tree:
- Initialize flags,
isSibling
andisCousin
, to manage sibling status and cousin detection. - Determine the number of nodes at the current level with
levelSize
, indicating how many nodes to process for this iteration. - Loop through each node at the current level:
- Poll the node from the queue to process it.
- If the node is
null
, reset theisSibling
flag. Anull
node acts as a marker to differentiate potential sibling groups. - Identify if the current node’s value matches either of the values being checked (
x
ory
):- If one match is found and
isCousin
is false, setisSibling
andisCousin
to true. - If a second match is found and
isSibling
is true, return!isSibling
to confirm they are cousins (since they shouldn’t be siblings).
- If one match is found and
- Push the left and right children of the current node into the queue.
- Push
null
into the queue after adding children to maintain sibling boundaries.
- If only one of the nodes (either
x
ory
) is found (isCousin
is true) and there was no sibling matched (isSibling
is false), continue to the next level.
- Initialize flags,
- Finally, if no companionship have been determined by the end of the loop, return
false
as the nodes are neither at the same level nor disconnected from having the same parent.
This method ensures that you efficiently identify if two nodes are cousins by maintaining clear control of level boundaries and sibling relationships.
from collections import deque
class Solution:
def checkCousins(self, root: TreeNode, p: int, q: int) -> bool:
# Initialize BFS queue
bfs_queue = deque([root])
while bfs_queue:
at_same_level = False
found_cousins = False
level_size = len(bfs_queue)
for _ in range(level_size):
# Dequeue element
curr_node = bfs_queue.popleft()
# Check if it's None that marks different parent boundary
if curr_node is None:
at_same_level = False
else:
# Check if current is either p or q
if curr_node.val == p or curr_node.val == q:
# If first of p or q is found at this level
if not found_cousins:
at_same_level, found_cousins = True, True
else:
# if they are still within the same parent boundary
return not at_same_level
# Continue BFS with children
if curr_node.left:
bfs_queue.append(curr_node.left)
if curr_node.right:
bfs_queue.append(curr_node.right)
# Marker for different parents
bfs_queue.append(None)
# Only one of p or q found at this level
if found_cousins:
return False
return False
In the provided Python code, you can determine if two nodes in a binary tree are cousins. The code employs a Breadth-First Search (BFS) strategy using a queue to traverse the tree level by level.
- Begin by initializing a deque to facilitate the BFS, starting with the root node.
- Use a while loop to process nodes until the queue is empty. For each level of the BFS:
- Initialize flags
at_same_level
to monitor if a found node's sibling might be the cousin andfound_cousins
to check if one of the cousin candidates was found at the current level. - Determine
level_size
as the count of nodes at the current tree level. - Iterate over each node of the current level:
- Dequeue the front node.
- Check if it is
None
which indicates the boundary between different parents within the same level. - Validate if the current node matches one of the target values (p or q). If a match is found:
- Set
found_cousins
toTrue
. If another target is found later in the same breadth level but before the nextNone
, they are cousins from different parents. - Check
at_same_level
to return a negative result if another target value is found after another sibling - indicating they are siblings instead of cousins.
- Set
- If the current node has children, enqueue them and place
None
as a marker for potential different parent boundaries.
- If after scanning a level only one target is found, determine that the other must be at a different level, thus not making them cousins, and return
False
.
- Initialize flags
- Execute BFS until all levels are visited. If no conclusive results emerge during the traversal, return
False
.
This Python code ensures an efficient check on whether two nodes are cousins in a binary tree without revisiting nodes or retaining unnecessary data, making use of the characteristics of BFS and control flags to ascertain cousin relation based on tree levels and parent boundaries.
No comments yet.