#50 ๐๐ณ 2641. Cousins in Binary Tree II ๐ง ๐
In this problem, weโre tasked with modifying a binary tree ๐ฒ by replacing the value of each node with the sum of all its cousinsโ values. Two nodes are considered cousins if they are at the same level but have different parents. This problem requires us to explore tree traversal techniques and depth-based operations, making it an exciting challenge for those familiar with binary trees and recursive algorithms! ๐โจ
Problem Statement ๐
Given the root of a binary tree, we must replace the value of each node with the sum of all its cousinsโ values. Cousins in a binary tree are nodes that:
- Are located at the same depth (i.e., have the same distance from the root).
- Have different parent nodes.
Our task is to return the modified tree, where every nodeโs value is the sum of its cousins.
Key Terms:
- Binary Tree: A tree structure in which each node has at most two children (left and right).
- Depth: The number of edges on the path from the root node to a given node. For example, the root node has a depth of 0.
- Cousins: Nodes that share the same depth but are not siblings (do not have the same parent).
Example Walkthroughs ๐งฉ
Example 1:
Input: root = [5,4,9,1,10,null,7]
Output: [0,0,0,7,7,null,11]
Explanation:
Hereโs the binary tree structure before modification:
5
/ \
4 9
/ \ \
1 10 7
Letโs break down the cousin relationships:
- Node
5
is at the root, so it has no cousins. Thus, its value is replaced with0
. - Nodes
4
and9
are at depth 1 but have no cousins, so their values are replaced with0
. - Node
1
(depth 2) has a cousin7
, so its value becomes7
. - Node
10
(depth 2) also has a cousin7
, so its value becomes7
. - Node
7
(depth 2) has cousins1
and10
, so its value becomes1 + 10 = 11
.
The tree after modification looks like this:
0
/ \
0 0
/ \ \
7 7 11
Example 2:
Input: root = [3,1,2]
Output: [0,0,0]
Explanation:
- Node
3
is the root, so its value becomes0
. - Nodes
1
and2
have no cousins, so their values become0
.
The tree after modification:
0
/ \
0 0
Tree Traversal and Cousin Relationships ๐ณ๐ค
To understand this problem, itโs crucial to revisit the concept of binary tree traversal. A binary tree is a hierarchical structure in which each node has a value, and each node may have up to two children: a left and a right child. To solve this problem, we need to traverse the tree in two passes, using Depth-First Search (DFS).
Depth-First Search (DFS) ๐ฒ๐
DFS is a traversal technique where we explore as far as possible along each branch before backtracking. In this problem, weโll use DFS to accomplish two things:
- First pass: Calculate the sum of node values at each depth.
- Second pass: For each node, update its value based on the sum of its cousins, which can be derived from the depth-level sum minus the values of the node itself and its sibling.
Step-by-Step Breakdown of the Solution ๐ถโโ๏ธ๐ง
Basic Solution Approach ๐ก
Step 1: Calculate the Sum of Nodes at Each Depth
We begin by traversing the tree and recording the sum of node values at each depth (or level). For instance, in the tree:
5
/ \
4 9
/ \ \
1 10 7
- At depth 0, the sum is
5
. - At depth 1, the sum is
4 + 9 = 13
. - At depth 2, the sum is
1 + 10 + 7 = 18
.
We can store these sums in a dictionary where the key is the depth and the value is the sum at that depth.
Step 2: Replace Node Values with Cousin Sums
Next, we perform a second traversal of the tree. For each node, we calculate the sum of its cousins by subtracting its value and its siblingโs value (if any) from the sum of values at its depth.
For example, in the tree:
5
/ \
4 9
/ \ \
1 10 7
For node 1
:
- The sum of all nodes at depth 2 is
18
. - Node
1
โs sibling is10
, so the sum of node1
โs cousins is18 - 1 - 10 = 7
.
For node 7
:
- The sum of all nodes at depth 2 is
18
. - Node
7
โs cousins are1
and10
, so its new value is1 + 10 = 11
.
Full Python Solution ๐
Letโs implement the solution using Python:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def replaceValueInTree(root: TreeNode) -> TreeNode:
if not root:
return None
# Step 1: DFS to calculate level sums
level_sums = {}
def dfs_sum(node, depth):
if not node:
return
if depth not in level_sums:
level_sums[depth] = 0
level_sums[depth] += node.val
dfs_sum(node.left, depth + 1)
dfs_sum(node.right, depth + 1)
dfs_sum(root, 0)
# Step 2: DFS to replace values with cousin sums
def dfs_replace(node, depth, sibling_val):
if not node:
return
# Cousin sum = total sum of the level - value of this node - sibling value
node.val = level_sums[depth] - node.val - sibling_val
left_val = node.left.val if node.left else 0
right_val = node.right.val if node.right else 0
dfs_replace(node.left, depth + 1, right_val)
dfs_replace(node.right, depth + 1, left_val)
dfs_replace(root, 0, 0)
return root
Walkthrough Example ๐
Letโs walk through a larger example to understand the solution in action.
Input:
8
/ \
3 10
/ \ \
1 6 14
/ \ /
4 7 13
Step 1: Calculate Level Sums
- Level 0: Sum =
8
- Level 1: Sum =
3 + 10 = 13
- Level 2: Sum =
1 + 6 + 14 = 21
- Level 3: Sum =
4 + 7 + 13 = 24
Step 2: Replace Values with Cousin Sums
- Level 0: The root node
8
has no cousins, so its value becomes0
. - Level 1:
- Node
3
has no cousins, so its value becomes0
. - Node
10
has no cousins, so its value becomes0
.
- Node
- Level 2:
- Node
1
has cousins6
and14
, so its value becomes6 + 14 = 20
. - Node
6
has cousins1
and14
, so its value becomes1 + 14 = 15
. - Node
14
has cousins1
and6
, so its value becomes1 + 6 = 7
.
- Node
- Level 3:
- Node
4
has cousins7
and13
, so its value becomes7 + 13 = 20
. - Node
7
has cousins4
and13
, so its value becomes4 + 13 = 17
. - Node
13
has cousins4
and7
, so its value becomes4 + 7 = 11
.
- Node
Final Output Tree:
0
/ \
0 0
/ \ \
20 15 7
/ \ /
20 17 11
Time Complexity Analysis โณ
Basic Solution
The time complexity for this approach is O(N), where N
is the number of nodes in the tree. This is because:
- The first DFS pass traverses the entire tree to calculate the level sums.
- The second DFS pass updates the node values based on the cousin sums, traversing the entire tree again.
Optimized Solution
This solution is already optimal in terms of time complexity. We traverse the tree twice in a depth-first manner, which ensures we visit each node in O(N) time.
Conclusion ๐ฏ
The Cousins in Binary Tree II problem offers a great opportunity to work with tree traversal techniques like DFS and understand how to manipulate tree structures based on relative node positions. By replacing node values with the sum of their cousins, we explore dynamic relationships in the tree. This is a solid exercise for anyone looking to deepen their understanding of binary trees! ๐๐ฒ