Skip to content

Commit 26e07f3

Browse files
committed
Added the code For path-sum iii
1 parent 7ce0d61 commit 26e07f3

File tree

2 files changed

+375
-1
lines changed

2 files changed

+375
-1
lines changed

dsa-problems/leetcode-problems/0400-0499.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export const problems = [
236236
"problemName": "437. Path Sum III",
237237
"difficulty": "Medium",
238238
"leetCodeLink": "https://leetcode.com/problems/path-sum-iii",
239-
"solutionLink": "#"
239+
"solutionLink": "/dsa-solutions/lc-solutions/0400-0499/path-sum-iii"
240240
},
241241
{
242242
"problemName": "438. Find All Anagrams in a String",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
---
2+
id: path-sum-iii
3+
title: Path Sum III
4+
sidebar_label: 0437 - Path Sum III
5+
tags:
6+
- Tree
7+
- Depth-First Search
8+
- Binary Tree
9+
description: "This is a solution to the Path Sum III problem on LeetCode."
10+
---
11+
12+
## Problem Description
13+
Given the root of a binary tree and an integer targetSum, return the number of paths where the sum of the values along the path equals targetSum.
14+
The path does not need to start or end at the root or a leaf, but it must go downwards (i.e., traveling only from parent nodes to child nodes).
15+
### Examples
16+
17+
**Example 1:**
18+
![image](https://assets.leetcode.com/uploads/2021/04/09/pathsum3-1-tree.jpg)
19+
```
20+
Input: root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
21+
Output: 3
22+
Explanation: The paths that sum to 8 are shown.
23+
```
24+
25+
**Example 2:**
26+
```
27+
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
28+
Output: 3
29+
```
30+
31+
### Constraints
32+
- The number of nodes in the tree is in the range [0, 1000].
33+
- `-10^9 <= Node.val <= 10^9`
34+
- `-1000 <= targetSum <= 1000`
35+
36+
## Solution for Path Sum III
37+
38+
### Approach
39+
#### Tree Traversal:
40+
41+
- The main idea is to traverse the binary tree. This is achieved using a recursive function solve that explores all nodes starting from the root.
42+
- The traversal is done using Depth First Search (DFS), ensuring all possible paths from the root to the leaves are explored.
43+
#### Path Tracking:
44+
- During traversal, we maintain a path vector that keeps track of the nodes' values along the current path from the root to the current node.
45+
- As we visit each node, its value is added to the path.
46+
#### Path Sum Calculation:
47+
- After adding a node’s value to the path, we check all sub-paths ending at the current node to see if any of them sum to the targetSum.
48+
- We iterate backwards through the path vector, accumulating the sum and checking if it matches the targetSum.
49+
- If a sub-path's sum matches targetSum, we increment the count.
50+
#### Backtracking:
51+
- After checking the sub-paths for the current node, we backtrack by removing the current node's value from the path.
52+
- This ensures that the path vector only contains nodes along the current path in the DFS traversal.
53+
54+
<Tabs>
55+
<TabItem value="Solution" label="Solution">
56+
57+
#### Implementation
58+
59+
```jsx live
60+
function pathSum3() {
61+
function TreeNode(val = 0, left = null, right = null) {
62+
this.val = val;
63+
this.left = left;
64+
this.right = right;
65+
}
66+
67+
function constructTreeFromArray(array) {
68+
if (!array.length) return null;
69+
70+
let root = new TreeNode(array[0]);
71+
let queue = [root];
72+
let i = 1;
73+
74+
while (i < array.length) {
75+
let currentNode = queue.shift();
76+
77+
if (array[i] !== null) {
78+
currentNode.left = new TreeNode(array[i]);
79+
queue.push(currentNode.left);
80+
}
81+
i++;
82+
83+
if (i < array.length && array[i] !== null) {
84+
currentNode.right = new TreeNode(array[i]);
85+
queue.push(currentNode.right);
86+
}
87+
i++;
88+
}
89+
return root;
90+
}
91+
function pathSum(root, targetSum) {
92+
// Map to keep the cumulative sum and its frequency.
93+
const prefixSumCount = new Map();
94+
95+
// Helper function to perform DFS on the tree and calculate paths.
96+
function dfs(node, currentSum) {
97+
if (!node) {
98+
return 0;
99+
}
100+
// Update the current sum by adding the node's value.
101+
currentSum += node.val;
102+
103+
// Get the number of times we have seen the currentSum - targetSum.
104+
let pathCount = prefixSumCount.get(currentSum - targetSum) || 0;
105+
106+
// Update the count of the current sum in the map.
107+
prefixSumCount.set(currentSum, (prefixSumCount.get(currentSum) || 0) + 1);
108+
109+
// Explore left and right subtrees.
110+
pathCount += dfs(node.left, currentSum);
111+
pathCount += dfs(node.right, currentSum);
112+
113+
// After returning from the recursion, decrement the frequency of the current sum.
114+
prefixSumCount.set(currentSum, (prefixSumCount.get(currentSum) || 0) - 1);
115+
116+
// Return the total count of paths found.
117+
return pathCount;
118+
}
119+
120+
// Initialize the map with base case before the recursion.
121+
prefixSumCount.set(0, 1);
122+
123+
// Start DFS from the root node with an initial sum of 0.
124+
return dfs(root, 0);
125+
}
126+
127+
const array =[10, 5, -3, 3, 2, null, 11, 3, -2, null, 1];
128+
const root = constructTreeFromArray(array)
129+
const input = root
130+
const targetSum = 8;
131+
const output = pathSum(input ,targetSum)
132+
return (
133+
<div>
134+
<p>
135+
<b>Input: </b>{JSON.stringify(array)}
136+
</p>
137+
<p>
138+
<b>Output:</b> {output.toString()}
139+
</p>
140+
</div>
141+
);
142+
}
143+
```
144+
145+
### Code in Different Languages
146+
147+
<Tabs>
148+
<TabItem value="JavaScript" label="JavaScript">
149+
<SolutionAuthor name="@hiteshgahanolia"/>
150+
```javascript
151+
function TreeNode(val, left = null, right = null) {
152+
return {
153+
val: val,
154+
left: left,
155+
right: right
156+
};
157+
}
158+
159+
function pathSum3(root, targetSum) {
160+
function solve(node, targetSum, count, path) {
161+
if (!node) {
162+
return;
163+
}
164+
path.push(node.val);
165+
pathSumHelper(node, targetSum, count, path);
166+
solve(node.left, targetSum, count, path.slice());
167+
solve(node.right, targetSum, count, path.slice());
168+
}
169+
170+
function pathSumHelper(node, targetSum, count, path) {
171+
let sum = 0;
172+
for (let i = path.length - 1; i >= 0; i--) {
173+
sum += path[i];
174+
if (sum === targetSum) {
175+
count[0]++;
176+
}
177+
}
178+
}
179+
180+
const path = [];
181+
const count = [0];
182+
solve(root, targetSum, count, path);
183+
return count[0];
184+
}
185+
```
186+
</TabItem>
187+
<TabItem value="TypeScript" label="TypeScript">
188+
<SolutionAuthor name="@hiteshgahanolia"/>
189+
```typescript
190+
interface TreeNode {
191+
val: number;
192+
left?: TreeNode | null;
193+
right?: TreeNode | null;
194+
}
195+
196+
function solve(root: TreeNode | null, targetSum: number, count: number[], path: number[]): void {
197+
if (!root) {
198+
return;
199+
}
200+
path.push(root.val);
201+
pathSumHelper(root, targetSum, count, path);
202+
solve(root.left, targetSum, count, path.slice());
203+
solve(root.right, targetSum, count, path.slice());
204+
}
205+
206+
function pathSumHelper(node: TreeNode, targetSum: number, count: number[], path: number[]): void {
207+
let sum = 0;
208+
for (let i = path.length - 1; i >= 0; i--) {
209+
sum += path[i];
210+
if (sum === targetSum) {
211+
count[0]++;
212+
}
213+
}
214+
}
215+
216+
function pathSum(root: TreeNode | null, targetSum: number): number {
217+
const path: number[] = [];
218+
const count: number[] = [0];
219+
solve(root, targetSum, count, path);
220+
return count[0];
221+
}
222+
```
223+
</TabItem>
224+
<TabItem value="Python" label="Python">
225+
<SolutionAuthor name="@hiteshgahanolia"/>
226+
```python
227+
class TreeNode:
228+
def __init__(self, val=0, left=None, right=None):
229+
self.val = val
230+
self.left = left
231+
self.right = right
232+
233+
class Solution:
234+
def solve(self, root, targetSum, count, path):
235+
if not root:
236+
return
237+
path.append(root.val)
238+
self.path_sum_helper(root, targetSum, count, path)
239+
self.solve(root.left, targetSum, count, path[:])
240+
self.solve(root.right, targetSum, count, path[:])
241+
242+
def path_sum_helper(self, node, targetSum, count, path):
243+
_sum = 0
244+
for val in reversed(path):
245+
_sum += val
246+
if _sum == targetSum:
247+
count[0] += 1
248+
249+
def pathSum(self, root, targetSum):
250+
path = []
251+
count = [0]
252+
self.solve(root, targetSum, count, path)
253+
return count[0]
254+
255+
```
256+
257+
</TabItem>
258+
<TabItem value="Java" label="Java">
259+
<SolutionAuthor name="@hiteshgahanolia"/>
260+
```
261+
import java.util.ArrayList;
262+
import java.util.List;
263+
264+
class TreeNode {
265+
int val;
266+
TreeNode left;
267+
TreeNode right;
268+
269+
TreeNode() {}
270+
271+
TreeNode(int val) {
272+
this.val = val;
273+
}
274+
275+
TreeNode(int val, TreeNode left, TreeNode right) {
276+
this.val = val;
277+
this.left = left;
278+
this.right = right;
279+
}
280+
}
281+
282+
public class Solution {
283+
public void solve(TreeNode root, int targetSum, int[] count, List<Integer> path) {
284+
if (root == null) {
285+
return;
286+
}
287+
path.add(root.val);
288+
pathSumHelper(root, targetSum, count, path);
289+
solve(root.left, targetSum, count, new ArrayList<>(path));
290+
solve(root.right, targetSum, count, new ArrayList<>(path));
291+
}
292+
293+
public void pathSumHelper(TreeNode node, int targetSum, int[] count, List<Integer> path) {
294+
int sum = 0;
295+
for (int i = path.size() - 1; i >= 0; i--) {
296+
sum += path.get(i);
297+
if (sum == targetSum) {
298+
count[0]++;
299+
}
300+
}
301+
}
302+
303+
public int pathSum(TreeNode root, int targetSum) {
304+
List<Integer> path = new ArrayList<>();
305+
int[] count = new int[1];
306+
solve(root, targetSum, count, path);
307+
return count[0];
308+
}
309+
}
310+
311+
```
312+
</TabItem>
313+
<TabItem value="C++" label="C++">
314+
<SolutionAuthor name="@hiteshgahanolia"/>
315+
316+
```cpp
317+
struct TreeNode {
318+
int val;
319+
TreeNode *left;
320+
TreeNode *right;
321+
TreeNode() : val(0), left(nullptr), right(nullptr) {}
322+
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
323+
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
324+
};
325+
void solve(TreeNode * root,int targetSum,int &count,vector<int>path)
326+
{
327+
if(root==NULL)
328+
{
329+
return;
330+
}
331+
path.push_back(root->val);
332+
solve(root->left,targetSum,count,path);
333+
solve(root->right,targetSum,count,path);
334+
335+
int size=path.size();
336+
long long sum=0;
337+
for(int i=size-1;i>=0;i--)
338+
{
339+
sum+=path[i];
340+
if(sum==targetSum)
341+
count++;
342+
}
343+
path.pop_back();
344+
}
345+
int pathSum(TreeNode* root, int targetSum) {
346+
vector<int>path;
347+
int count=0;
348+
solve(root,targetSum,count,path);
349+
return count;
350+
}
351+
```
352+
</TabItem>
353+
</Tabs>
354+
355+
#### Complexity Analysis
356+
##### Time Complexity:
357+
- Tree Traversal (DFS):
358+
We visit each node exactly once during the Depth First Search (DFS). For a binary tree with n nodes, this traversal takes $O(n)$ time.
359+
360+
- Sub-Path Sum Calculation:
361+
At each node, we check all sub-paths ending at that node. The maximum number of sub-paths to check is equal to the depth of the tree, which in the worst case (a skewed tree) is
362+
$O(n)$.Thus, for each node, the sum checking operation takes $O(n)$ in the worst case.
363+
Combining these two parts, the total time complexity is
364+
$O(n)$×$O(n)$=$O(n^2)$ in the worst case.
365+
##### Space Complexity: $O(N)$
366+
</TabItem>
367+
</Tabs>
368+
369+
## References
370+
371+
- **LeetCode Problem**: [Path Sum III](https://leetcode.com/problems/path-sum-iii/description/)
372+
373+
- **Solution Link**: [LeetCode Solution](https://leetcode.com/problems/path-sum-iii/solutions)
374+

0 commit comments

Comments
 (0)