Skip to content

Commit 6030d04

Browse files
authored
Merge pull request #1296 from shreyash3087/add/leetcode-563
Docs: Added Solutions to Leetcode 563
2 parents 4aa75b7 + 1e4b35a commit 6030d04

File tree

2 files changed

+212
-1
lines changed

2 files changed

+212
-1
lines changed

dsa-problems/leetcode-problems/0500-0599.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ export const problems =[
374374
"problemName": "563. Binary Tree Tilt",
375375
"difficulty": "Easy",
376376
"leetCodeLink": "https://leetcode.com/problems/binary-tree-tilt",
377-
"solutionLink": "#"
377+
"solutionLink": "/dsa-solutions/lc-solutions/0500-0599/binary-tree-tilt"
378378
},
379379
{
380380
"problemName": "564. Find the Closest Palindrome",
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
id: binary-tree-tilt
3+
title: Binary Tree Tilt
4+
sidebar_label: 0563 - Binary Tree Tilt
5+
tags:
6+
- Recursion
7+
- Depth First Search
8+
- Binary Tree
9+
description: "This is a solution to the Binary Tree Tilt problem on LeetCode."
10+
---
11+
12+
## Problem Description
13+
14+
Given the root of a binary tree, return the sum of every tree node's **tilt**.
15+
16+
The **tilt** of a tree node is the **absolute difference** between the sum of all left subtree node values and all right subtree node **values**. If a node does not have a left child, then the sum of the left subtree node **values** is treated as `0`. The rule is similar if the node does not have a right child.
17+
18+
### Examples
19+
**Example 1:**
20+
21+
![image](https://assets.leetcode.com/uploads/2020/10/20/tilt1.jpg)
22+
```
23+
Input: root = [1,2,3]
24+
Output: 1
25+
Explanation:
26+
Tilt of node 2 : |0-0| = 0 (no children)
27+
Tilt of node 3 : |0-0| = 0 (no children)
28+
Tilt of node 1 : |2-3| = 1 (left subtree is just left child, so sum is 2; right subtree is just right child, so sum is 3)
29+
Sum of every tilt : 0 + 0 + 1 = 1
30+
```
31+
32+
**Example 2:**
33+
34+
![image](https://assets.leetcode.com/uploads/2020/10/20/tilt2.jpg)
35+
```
36+
Input: root = [4,2,9,3,5,null,7]
37+
Output: 15
38+
Explanation:
39+
Tilt of node 3 : |0-0| = 0 (no children)
40+
Tilt of node 5 : |0-0| = 0 (no children)
41+
Tilt of node 7 : |0-0| = 0 (no children)
42+
Tilt of node 2 : |3-5| = 2 (left subtree is just left child, so sum is 3; right subtree is just right child, so sum is 5)
43+
Tilt of node 9 : |0-7| = 7 (no left child, so sum is 0; right subtree is just right child, so sum is 7)
44+
Tilt of node 4 : |(3+5+2)-(9+7)| = |10-16| = 6 (left subtree values are 3, 5, and 2, which sums to 10; right subtree values are 9 and 7, which sums to 16)
45+
Sum of every tilt : 0 + 0 + 0 + 2 + 7 + 6 = 15
46+
```
47+
48+
### Constraints
49+
50+
- The number of nodes in the tree is in the range [0, $10^4$].
51+
- `1000 <= Node.val <= 1000`
52+
53+
## Solution for Binary Tree Tilt
54+
55+
### Overview
56+
First of all, let us clarify the concept of **tilt** for a given node in a tree.
57+
58+
In order to calculate the tilt value for a node, we need to know the sum of nodes in its left and right subtrees respectively.
59+
60+
Assume that we have a function `valueSum(node)` which gives the sum of all nodes, starting from the input node, then the sum of the node's left subtree would be `valueSum(node.left)`.
61+
Similarly, the sum of its right subtree would be `valueSum(node.right)`.
62+
63+
With the above functions, we can then define the tilt value of a node as follows:
64+
65+
$tilt(node)=∣valueSum(node.left)−valueSum(node.right)∣$
66+
67+
Given the above formula, we show an example on how the tilt value of each node looks like, in the following graph:
68+
69+
![image](https://assets.leetcode.com/static_assets/media/original_images/563/563_tilt_example.png)
70+
Note: when a subtree is empty, its value sum is zero.
71+
As a result, the tilt value for a leaf node would be zero, since both the left and right subtree of a leaf node are empty.
72+
73+
### Approach 1: Post-Order DFS Traversal
74+
#### Intuition
75+
76+
> The overall idea is that we traverse each node, and calculate the tilt value for each node. At the end, we sum up all the tilt values, which is the desired result of the problem.
77+
78+
There are in general two strategies to traverse a tree data structure, namely Breadth-First Search (**BFS**) and Depth-First Search (**DFS**).
79+
80+
Concerning the DFS strategy, it can further be divided into three categories: Pre-Order, In-Order and Post-Order, depending on the relative order of visit among the node and its children nodes.
81+
82+
Sometimes, both strategies could work for a specific problem. In other cases, one of them might be more adapted to the problem.
83+
In our case here, the DFS is a more optimized choice, as one will see later.
84+
More specifically, we could apply the **Post-Order DFS** traversal here.
85+
86+
#### Algorithm
87+
As we discussed before, in order to calculate the tilt value for a node, we need to calculate the sum of its left and right subtrees respectively.
88+
89+
Let us first implement the function `valueSum(node)` which returns the sum of values for all nodes starting from the given `node`, which can be summarized with the following recursive formula:
90+
91+
$valueSum(node)=node.val+valueSum(node.left)+valueSum(node.right)$
92+
93+
Furthermore, the tilt value of a node also depends on the value sum of its left and right subtrees, as follows:
94+
95+
$tilt(node)=∣valueSum(node.left)−valueSum(node.right)∣$
96+
97+
Intuitively, we could combine the above calculations within a single recursive function.
98+
In this way, we only need to traverse each node once and only once.
99+
100+
> More specifically, we will traverse the tree in the post-order DFS, i.e. we visit a node's left and right subtrees before processing the value of the current node.
101+
102+
## Code in Different Languages
103+
104+
<Tabs>
105+
<TabItem value="cpp" label="C++">
106+
<SolutionAuthor name="@Shreyash3087"/>
107+
108+
```cpp
109+
#include <cmath>
110+
111+
class Solution {
112+
private:
113+
int totalTilt;
114+
115+
int valueSum(TreeNode* node) {
116+
if (node == nullptr)
117+
return 0;
118+
119+
int leftSum = valueSum(node->left);
120+
int rightSum = valueSum(node->right);
121+
int tilt = std::abs(leftSum - rightSum);
122+
totalTilt += tilt;
123+
124+
return node->val + leftSum + rightSum;
125+
}
126+
127+
public:
128+
int findTilt(TreeNode* root) {
129+
totalTilt = 0;
130+
valueSum(root);
131+
return totalTilt;
132+
}
133+
};
134+
135+
```
136+
</TabItem>
137+
<TabItem value="java" label="Java">
138+
<SolutionAuthor name="@Shreyash3087"/>
139+
140+
```java
141+
class Solution {
142+
private int totalTilt = 0;
143+
144+
protected int valueSum(TreeNode node) {
145+
if (node == null)
146+
return 0;
147+
148+
int leftSum = this.valueSum(node.left);
149+
int rightSum = this.valueSum(node.right);
150+
int tilt = Math.abs(leftSum - rightSum);
151+
this.totalTilt += tilt;
152+
153+
// return the sum of values starting from this node.
154+
return node.val + leftSum + rightSum;
155+
}
156+
157+
public int findTilt(TreeNode root) {
158+
this.totalTilt = 0;
159+
this.valueSum(root);
160+
return this.totalTilt;
161+
}
162+
}
163+
```
164+
165+
</TabItem>
166+
<TabItem value="python" label="Python">
167+
<SolutionAuthor name="@Shreyash3087"/>
168+
169+
```python
170+
class Solution:
171+
def findTilt(self, root: TreeNode) -> int:
172+
total_tilt = 0
173+
174+
def valueSum(node):
175+
nonlocal total_tilt
176+
177+
if not node:
178+
return 0
179+
180+
left_sum = valueSum(node.left)
181+
right_sum = valueSum(node.right)
182+
tilt = abs(left_sum - right_sum)
183+
total_tilt += tilt
184+
185+
return left_sum + right_sum + node.val
186+
187+
valueSum(root)
188+
189+
return total_tilt
190+
```
191+
</TabItem>
192+
</Tabs>
193+
194+
## Complexity Analysis
195+
196+
### Time Complexity: $O(N)$
197+
198+
> **Reason**: We traverse each node once and only once. During the traversal, we calculate the tilt value for each node.
199+
200+
### Space Complexity: $O(N)$
201+
202+
> **Reason**:
203+
> - Although the variables that we used in the algorithm are of constant-size, we applied recursion in the algorithm which incurs additional memory consumption in function call stack.
204+
>
205+
> - In the worst case where the tree is not well balanced, the recursion could pile up N times. As a result, the space complexity of the algorithm is O(N).
206+
207+
## References
208+
209+
- **LeetCode Problem**: [Binary Tree Tilt](https://leetcode.com/problems/binary-tree-tilt/description/)
210+
211+
- **Solution Link**: [Binary Tree Tilt](https://leetcode.com/problems/binary-tree-tilt/solutions/)

0 commit comments

Comments
 (0)