You are given the root of a binary tree. A node is considered lonely if it is the only child of its parent.
Return an array containing the values of all lonely nodes in the tree. Return the list in any order.
Example 1:
Input: root = [1,2,3,null,4] Output: [4] Explanation: The node with value 2 is the only child of the node with value 1.The node with value 4 is the only child of the node with value 2. Hence the lonely nodes are [4].
Example 2:
Input: root = [7,1,4,6,null,5,3,null,null,null,null,null,2] Output: [6,2] Explanation: The node with value 1 is the only child of the node with value 7.The node with value 6 is the only child of the node with value 1.The node with value 5 is the only child of the node with value 4.The node with value 2 is the only child of the node with value 3. Hence the lonely nodes are [6, 2].
Example 3:
Input: root = [11,99,88,77,null,null,66,55,null,null,44,33,null,null,22] Output: [77,55,44,33,22] Explanation: Nodes with values 99 and 88 have no siblings.
Constraints:
[1, 1000].1 <= Node.val <= 106When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're trying to find all the 'lonely' nodes in a family tree. The brute force way to do this is to look at every single person in the tree and check their siblings. If they don't have a sibling, they're lonely.
Here's how the algorithm would work step-by-step:
def find_lonely_nodes_brute_force(root):
lonely_nodes = []
def traverse(node):
if not node:
return
# Check if current node has exactly one child
if (node.left and not node.right) or (not node.left and node.right):
# Add the single child to the lonely_nodes list
if node.left:
lonely_nodes.append(node.left.val)
else:
lonely_nodes.append(node.right.val)
# Recursively traverse left and right subtrees
traverse(node.left)
traverse(node.right)
traverse(root)
return lonely_nodesThe goal is to identify nodes in a binary tree that are 'lonely', meaning they have a parent but no sibling. We can efficiently find these lonely nodes by traversing the tree and checking each node's children.
Here's how the algorithm would work step-by-step:
def find_lonely_nodes(root):
lonely_node_values = []
def traverse_tree(node):
if not node:
return
# Check if the current node has only one child
if node.left and not node.right:
lonely_node_values.append(node.left.val)
if node.right and not node.left:
# Add the lonely node's value to the list
lonely_node_values.append(node.right.val)
traverse_tree(node.left)
# Recursively check the right subtree for lonely nodes
traverse_tree(node.right)
traverse_tree(root)
return lonely_node_values| Case | How to Handle |
|---|---|
| Null or Empty Tree | Return an empty list if the root is null, indicating no lonely nodes exist. |
| Single Node Tree | Return an empty list because a single node cannot be lonely. |
| Complete Binary Tree (no lonely nodes) | The algorithm should iterate through the tree and return an empty list if no lonely nodes are found. |
| Highly Skewed Tree (all nodes on one side) | The traversal should still correctly identify lonely nodes in skewed trees. |
| Tree with duplicate values | The algorithm should correctly identify lonely nodes regardless of duplicate values; the node's position is what matters, not the value. |
| Tree with negative, zero, and positive values | The node values should not affect the logic of identifying lonely nodes, which depends solely on the tree structure. |
| Maximum Tree Depth (potential stack overflow with recursion) | Use an iterative approach (e.g., Breadth-First Search) to avoid stack overflow issues with very deep trees instead of recursive Depth First Search. |
| Tree with only lonely nodes | The algorithm correctly collects all node values that fulfill the 'lonely node' criterion into the result list. |