2440. Create Components With Same Value
Problem Description
You have an undirected tree with n
nodes labeled from 0
to n - 1
. Each node i
has a value given by nums[i]
, where nums
is a 0-indexed array of length n
. The tree structure is defined by an array edges
of length n - 1
, where each edges[i] = [ai, bi]
represents an edge between nodes ai
and bi
.
Your task is to delete some edges from the tree, which will split it into multiple connected components. The value of each component is defined as the sum of all nums[i]
values for nodes i
within that component.
The goal is to find the maximum number of edges you can delete such that all resulting connected components have the same value.
For example, if you delete k
edges, you'll create k + 1
connected components. All these components must have equal sums of their node values.
The problem asks you to return the maximum number of edges that can be deleted while maintaining this equal-value constraint across all components.
Key points to understand:
- The tree initially has
n
nodes andn - 1
edges (as it's a tree) - Deleting edges creates multiple subtrees (connected components)
- Each component's value is the sum of its nodes' values
- All components must have exactly the same total value
- You want to maximize the number of deleted edges (which maximizes the number of components)
Flowchart Walkthrough
First, let's pin down the algorithm using the Flowchart. Here's a step-by-step walkthrough:
Is it a graph?
- Yes: The problem explicitly involves an undirected tree with nodes and edges. A tree is a special type of graph (connected acyclic graph).
Is it a tree?
- Yes: The problem states we have an undirected tree with
n
nodes andn-1
edges, which is the definition of a tree structure.
DFS
- Yes: Since we're dealing with a tree structure, DFS (Depth-First Search) is the recommended approach.
Conclusion: The flowchart leads us directly to using DFS for this tree problem.
Why DFS is Appropriate
The DFS pattern fits perfectly for this problem because:
-
Tree Traversal: We need to traverse the tree to calculate subtree sums from bottom to top.
-
Subtree Value Calculation: DFS allows us to recursively compute the sum of values in each subtree. We can process children first, then aggregate their values at the parent node.
-
Component Detection: When we find a subtree whose sum equals our target value (
s/k
), we can "cut" it off by returning 0 to the parent, effectively simulating edge deletion. -
Validation: DFS helps us validate whether a given partition scheme is feasible by checking if we can form components with equal values throughout the entire tree.
The solution uses DFS to explore different possibilities of dividing the tree into k
components, where each component has value s/k
. By traversing from leaves to root, we can determine which edges to cut to create the desired equal-valued components.
Intuition
Let's think about what happens when we delete edges. If we delete k-1
edges, we create exactly k
connected components. For all components to have equal value, each component must have value total_sum / k
.
The key insight is that total_sum / k
must be an integer for a valid partition to exist. This immediately limits our choices for k
- we can only consider values of k
that evenly divide the total sum.
Now, how do we check if we can actually create k
components with equal values? We need to verify that we can partition the tree into subtrees where each has exactly value target = total_sum / k
.
Here's where DFS becomes crucial. Starting from any node (say node 0), we can traverse the tree and calculate subtree sums. When we encounter a subtree whose sum equals our target value, we know we can "cut" it off from its parent - this represents deleting an edge. We mark this by returning 0 to the parent, indicating this subtree has been separated.
But what if a subtree's sum exceeds the target? This means our current choice of k
is invalid - we can't create equal-valued components with this target. We return -1 to signal failure.
To maximize the number of edges deleted (which means maximizing k
), we try values of k
from large to small. The first valid k
we find gives us the maximum number of components possible, and thus the maximum number of edges we can delete is k-1
.
There's also an optimization: the maximum possible k
is bounded by min(n, total_sum / max_value)
, because each component must contain at least one node, and the smallest possible component value is at least the maximum node value in the tree.
The beauty of this approach is that DFS naturally handles the tree structure and allows us to make greedy decisions - whenever we find a valid subtree of the target size, we can immediately "cut" it, knowing this won't prevent us from finding other valid partitions in the remaining tree.
Learn more about Tree, Depth-First Search and Math patterns.
Solution Approach
Let's walk through the implementation step by step:
1. Graph Representation
First, we build an adjacency list representation of the tree using a defaultdict(list)
. For each edge [a, b]
, we add b
to g[a]
and a
to g[b]
since it's an undirected tree.
2. Enumeration of k (Number of Components)
We calculate:
s = sum(nums)
: Total sum of all node valuesmx = max(nums)
: Maximum value among all nodes- Starting
k = min(n, s // mx)
: The maximum possible number of components
We iterate k
from this maximum value down to 2 (since k=1
means no edges deleted). For each k
, we check if s % k == 0
. If not, we skip this k
since we can't divide the sum evenly.
3. DFS Function for Validation
For each valid k
, we set t = s // k
as our target component value and use DFS to check if we can partition the tree:
def dfs(i, fa):
x = nums[i] # Start with current node's value
for j in g[i]:
if j != fa: # Avoid going back to parent
y = dfs(j, i) # Get subtree sum from child
if y == -1:
return -1 # Propagate failure
x += y # Add child's contribution
if x > t:
return -1 # Subtree sum exceeds target - invalid
return x if x < t else 0 # Return sum or 0 if we found a complete component
The DFS logic:
- Start with the current node's value
- Recursively calculate sums from all children (excluding parent to avoid cycles)
- If any child returns
-1
, propagate the failure upward - Add valid child contributions to current subtree sum
- If subtree sum equals target
t
, return0
(indicating this subtree can be cut off) - If subtree sum is less than
t
, return the sum (this subtree needs to be combined with others) - If subtree sum exceeds
t
, return-1
(invalid partition)
4. Finding the Answer
We start DFS from node 0 with parent -1
. If dfs(0, -1)
returns 0
, it means we successfully partitioned the entire tree into k
components of equal value. We return k - 1
as the number of edges deleted.
If no valid partition is found for any k
, we return 0
(no edges can be deleted while maintaining equal component values).
Time Complexity: O(n * d)
where d
is the number of divisors of s
. In the worst case, this could be O(n²)
.
Space Complexity: O(n)
for the adjacency list and recursion stack.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to illustrate the solution approach.
Example:
nums = [6, 2, 2, 2, 6]
(5 nodes with these values)edges = [[0,1], [1,2], [1,3], [3,4]]
The tree structure looks like:
0(6) | 1(2) / \ 2(2) 3(2) | 4(6)
Step 1: Calculate total sum and maximum value
- Total sum
s = 6 + 2 + 2 + 2 + 6 = 18
- Maximum value
mx = 6
- Maximum possible components
k = min(5, 18//6) = min(5, 3) = 3
Step 2: Try k = 3 (attempting to create 3 components)
- Check if
18 % 3 == 0
✓ (Yes, it divides evenly) - Target value per component:
t = 18/3 = 6
Step 3: Run DFS from node 0
Let's trace through the DFS:
- Start at node 0 (value = 6)
- Visit child 1
- At node 1 (value = 2)
- Visit child 2
- Node 2 is a leaf with value 2
- Returns 2 (less than target 6)
- Visit child 3
- At node 3 (value = 2)
- Visit child 4
- Node 4 is a leaf with value 6
- Returns 0 (equals target, can be cut off!)
- Node 3:
x = 2 + 0 = 2
- Returns 2 (less than target)
- Visit child 4
- At node 3 (value = 2)
- Node 1:
x = 2 + 2 + 2 = 6
- Returns 0 (equals target, can be cut off!)
- Visit child 2
- Back at node 0:
x = 6 + 0 = 6
- Returns 0 (equals target)
Result: DFS returns 0, meaning we successfully created 3 components:
- Component 1: Node 0 alone (sum = 6)
- Component 2: Nodes 1, 2, 3 (sum = 2+2+2 = 6)
- Component 3: Node 4 alone (sum = 6)
We deleted 2 edges to create these 3 components.
Step 4: Check if we can do better with k = 2
- Target would be
18/2 = 9
- Running DFS would fail because no valid partition exists where each component sums to 9
Final Answer: Maximum edges we can delete = 2
The algorithm efficiently found that we can partition the tree into 3 equal-valued components by removing the edges between nodes 0-1 and nodes 3-4.
Solution Implementation
1from typing import List
2from collections import defaultdict
3
4class Solution:
5 def componentValue(self, nums: List[int], edges: List[List[int]]) -> int:
6 """
7 Find the maximum number of edges that can be deleted from the tree
8 such that all resulting components have equal sum.
9
10 Args:
11 nums: Node values
12 edges: Tree edges connecting nodes
13
14 Returns:
15 Maximum number of edges that can be deleted
16 """
17
18 def dfs(node: int, parent: int) -> int:
19 """
20 Perform DFS to check if we can partition the subtree rooted at 'node'
21 into components of size 'target_sum'.
22
23 Args:
24 node: Current node
25 parent: Parent of current node
26
27 Returns:
28 Remainder sum after forming complete components, or -1 if impossible
29 """
30 # Start with the value of current node
31 subtree_sum = nums[node]
32
33 # Process all children
34 for neighbor in adjacency_list[node]:
35 if neighbor != parent:
36 # Get the remainder from child's subtree
37 child_remainder = dfs(neighbor, node)
38
39 # If child subtree cannot be partitioned properly, propagate failure
40 if child_remainder == -1:
41 return -1
42
43 # Add child's remainder to current subtree sum
44 subtree_sum += child_remainder
45
46 # If subtree sum exceeds target, partitioning is impossible
47 if subtree_sum > target_sum:
48 return -1
49
50 # If subtree sum equals target, we can cut here (return 0 remainder)
51 # Otherwise, return the current sum as remainder for parent
52 return 0 if subtree_sum == target_sum else subtree_sum
53
54 # Build adjacency list for the tree
55 num_nodes = len(nums)
56 adjacency_list = defaultdict(list)
57 for node_a, node_b in edges:
58 adjacency_list[node_a].append(node_b)
59 adjacency_list[node_b].append(node_a)
60
61 # Calculate total sum and maximum value
62 total_sum = sum(nums)
63 max_value = max(nums)
64
65 # Try different numbers of components (from maximum possible down to 2)
66 # Each component must have sum = total_sum / num_components
67 max_components = min(num_nodes, total_sum // max_value)
68
69 for num_components in range(max_components, 1, -1):
70 # Check if total sum can be evenly divided into num_components parts
71 if total_sum % num_components == 0:
72 target_sum = total_sum // num_components
73
74 # Try to partition the tree with this target sum
75 if dfs(0, -1) == 0:
76 # If successful, return number of cuts (components - 1)
77 return num_components - 1
78
79 # No valid partition found, return 0 (no edges can be deleted)
80 return 0
81
1class Solution {
2 // Adjacency list representation of the tree
3 private List<Integer>[] adjacencyList;
4 // Array storing node values
5 private int[] nodeValues;
6 // Target sum for each component
7 private int targetSum;
8
9 public int componentValue(int[] nums, int[][] edges) {
10 int n = nums.length;
11
12 // Initialize the graph and node values
13 adjacencyList = new List[n];
14 this.nodeValues = nums;
15 Arrays.setAll(adjacencyList, index -> new ArrayList<>());
16
17 // Build the undirected tree from edges
18 for (int[] edge : edges) {
19 int nodeA = edge[0];
20 int nodeB = edge[1];
21 adjacencyList[nodeA].add(nodeB);
22 adjacencyList[nodeB].add(nodeA);
23 }
24
25 // Calculate total sum and maximum value in the array
26 int totalSum = sum(nums);
27 int maxValue = max(nums);
28
29 // Try different number of components from maximum possible down to 2
30 // Maximum components is limited by min(n, totalSum/maxValue)
31 for (int numComponents = Math.min(n, totalSum / maxValue); numComponents > 1; numComponents--) {
32 // Check if total sum can be evenly divided into numComponents parts
33 if (totalSum % numComponents == 0) {
34 targetSum = totalSum / numComponents;
35
36 // Perform DFS to check if tree can be split into components with targetSum
37 if (dfs(0, -1) == 0) {
38 // Return number of edges to delete (components - 1)
39 return numComponents - 1;
40 }
41 }
42 }
43
44 // No valid split found
45 return 0;
46 }
47
48 /**
49 * DFS to check if subtree can form valid components
50 * @param currentNode - current node being processed
51 * @param parent - parent of current node to avoid revisiting
52 * @return subtree sum if less than target, 0 if equals target (component formed), -1 if invalid
53 */
54 private int dfs(int currentNode, int parent) {
55 // Start with current node's value
56 int subtreeSum = nodeValues[currentNode];
57
58 // Traverse all children (adjacent nodes except parent)
59 for (int neighbor : adjacencyList[currentNode]) {
60 if (neighbor != parent) {
61 // Recursively get sum from child subtree
62 int childSum = dfs(neighbor, currentNode);
63
64 // If child subtree is invalid, propagate failure
65 if (childSum == -1) {
66 return -1;
67 }
68
69 // Add valid child sum to current subtree sum
70 subtreeSum += childSum;
71 }
72 }
73
74 // If subtree sum exceeds target, this split is invalid
75 if (subtreeSum > targetSum) {
76 return -1;
77 }
78
79 // If subtree sum equals target, we can cut here (return 0)
80 // Otherwise, return the partial sum to be used by parent
81 return subtreeSum < targetSum ? subtreeSum : 0;
82 }
83
84 /**
85 * Calculate sum of all elements in array
86 */
87 private int sum(int[] arr) {
88 int totalSum = 0;
89 for (int value : arr) {
90 totalSum += value;
91 }
92 return totalSum;
93 }
94
95 /**
96 * Find maximum element in array
97 */
98 private int max(int[] arr) {
99 int maxValue = arr[0];
100 for (int value : arr) {
101 maxValue = Math.max(maxValue, value);
102 }
103 return maxValue;
104 }
105}
106
1class Solution {
2public:
3 int componentValue(vector<int>& nums, vector<vector<int>>& edges) {
4 int nodeCount = nums.size();
5 int totalSum = accumulate(nums.begin(), nums.end(), 0);
6 int maxValue = *max_element(nums.begin(), nums.end());
7
8 // Build adjacency list representation of the tree
9 unordered_map<int, vector<int>> adjacencyList;
10 for (auto& edge : edges) {
11 int nodeA = edge[0];
12 int nodeB = edge[1];
13 adjacencyList[nodeA].push_back(nodeB);
14 adjacencyList[nodeB].push_back(nodeA);
15 }
16
17 // Target sum for each component after splitting
18 int targetComponentSum = 0;
19
20 // DFS function to check if we can split the tree into components with target sum
21 // Returns the sum of the subtree that needs to be carried forward to parent
22 // Returns -1 if it's impossible to achieve the target split
23 // Returns 0 if the subtree forms a complete component with target sum
24 function<int(int, int)> checkSplit = [&](int currentNode, int parent) -> int {
25 // Start with current node's value
26 int subtreeSum = nums[currentNode];
27
28 // Process all children (excluding parent to avoid revisiting)
29 for (int neighbor : adjacencyList[currentNode]) {
30 if (neighbor != parent) {
31 int childResult = checkSplit(neighbor, currentNode);
32
33 // If child subtree cannot form valid components, propagate failure
34 if (childResult == -1) {
35 return -1;
36 }
37
38 // Add the partial sum from child if it's not a complete component
39 subtreeSum += childResult;
40 }
41 }
42
43 // If subtree sum exceeds target, it's impossible to form valid components
44 if (subtreeSum > targetComponentSum) {
45 return -1;
46 }
47
48 // If subtree sum equals target, this forms a complete component (return 0)
49 // Otherwise, return the partial sum to be added to parent's calculation
50 return (subtreeSum < targetComponentSum) ? subtreeSum : 0;
51 };
52
53 // Try different number of components from maximum possible down to 2
54 // Maximum components is limited by min(nodeCount, totalSum/maxValue)
55 // since each component must have at least maxValue sum
56 for (int componentCount = min(nodeCount, totalSum / maxValue); componentCount > 1; --componentCount) {
57 // Check if total sum can be evenly divided into componentCount parts
58 if (totalSum % componentCount == 0) {
59 targetComponentSum = totalSum / componentCount;
60
61 // Check if tree can be split into componentCount components
62 // Start DFS from node 0 with no parent (-1)
63 if (checkSplit(0, -1) == 0) {
64 // Return number of edges to remove (componentCount - 1)
65 return componentCount - 1;
66 }
67 }
68 }
69
70 // No valid split found, return 0
71 return 0;
72 }
73};
74
1function componentValue(nums: number[], edges: number[][]): number {
2 const nodeCount = nums.length;
3 const totalSum = nums.reduce((sum, num) => sum + num, 0);
4 const maxValue = Math.max(...nums);
5
6 // Build adjacency list representation of the tree
7 const adjacencyList: Map<number, number[]> = new Map();
8 for (const edge of edges) {
9 const nodeA = edge[0];
10 const nodeB = edge[1];
11 if (!adjacencyList.has(nodeA)) {
12 adjacencyList.set(nodeA, []);
13 }
14 if (!adjacencyList.has(nodeB)) {
15 adjacencyList.set(nodeB, []);
16 }
17 adjacencyList.get(nodeA)!.push(nodeB);
18 adjacencyList.get(nodeB)!.push(nodeA);
19 }
20
21 // Target sum for each component after splitting
22 let targetComponentSum = 0;
23
24 // DFS function to check if we can split the tree into components with target sum
25 // Returns the sum of the subtree that needs to be carried forward to parent
26 // Returns -1 if it's impossible to achieve the target split
27 // Returns 0 if the subtree forms a complete component with target sum
28 const checkSplit = (currentNode: number, parent: number): number => {
29 // Start with current node's value
30 let subtreeSum = nums[currentNode];
31
32 // Process all children (excluding parent to avoid revisiting)
33 const neighbors = adjacencyList.get(currentNode) || [];
34 for (const neighbor of neighbors) {
35 if (neighbor !== parent) {
36 const childResult = checkSplit(neighbor, currentNode);
37
38 // If child subtree cannot form valid components, propagate failure
39 if (childResult === -1) {
40 return -1;
41 }
42
43 // Add the partial sum from child if it's not a complete component
44 subtreeSum += childResult;
45 }
46 }
47
48 // If subtree sum exceeds target, it's impossible to form valid components
49 if (subtreeSum > targetComponentSum) {
50 return -1;
51 }
52
53 // If subtree sum equals target, this forms a complete component (return 0)
54 // Otherwise, return the partial sum to be added to parent's calculation
55 return subtreeSum < targetComponentSum ? subtreeSum : 0;
56 };
57
58 // Try different number of components from maximum possible down to 2
59 // Maximum components is limited by min(nodeCount, totalSum/maxValue)
60 // since each component must have at least maxValue sum
61 for (let componentCount = Math.min(nodeCount, Math.floor(totalSum / maxValue)); componentCount > 1; componentCount--) {
62 // Check if total sum can be evenly divided into componentCount parts
63 if (totalSum % componentCount === 0) {
64 targetComponentSum = totalSum / componentCount;
65
66 // Check if tree can be split into componentCount components
67 // Start DFS from node 0 with no parent (-1)
68 if (checkSplit(0, -1) === 0) {
69 // Return number of edges to remove (componentCount - 1)
70 return componentCount - 1;
71 }
72 }
73 }
74
75 // No valid split found, return 0
76 return 0;
77}
78
Time and Space Complexity
Time Complexity: O(n × √s)
The algorithm iterates through possible values of k
from min(n, s // mx)
down to 2
. The key insight is that we're looking for divisors of s
(the sum of all node values). The number of divisors of s
is bounded by O(√s)
in the average case, though it can be O(s^(1/3))
in the worst case for highly composite numbers. However, the practical bound used here is O(√s)
.
For each valid divisor (when s % k == 0
), we perform a DFS traversal of the tree which takes O(n)
time, where n
is the number of nodes. The DFS visits each node exactly once and processes each edge twice (once from each direction).
Therefore, the total time complexity is O(number of divisors × DFS cost) = O(√s × n) = O(n × √s)
.
Space Complexity: O(n)
The space complexity consists of:
- The adjacency list
g
which stores all edges:O(n)
space (since a tree withn
nodes hasn-1
edges) - The recursive call stack for DFS which can go up to depth
O(n)
in the worst case (when the tree is a linear chain) - Other variables like
s
,mx
,t
,k
which useO(1)
space
The dominant factor is the recursion stack and adjacency list, both of which are O(n)
, giving us a total space complexity of O(n)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Handling of Component Detection in DFS
A common mistake is misunderstanding when a subtree forms a complete component. Consider this incorrect implementation:
def dfs(node, parent):
subtree_sum = nums[node]
for neighbor in adjacency_list[node]:
if neighbor != parent:
child_sum = dfs(neighbor, node)
if child_sum == -1:
return -1
subtree_sum += child_sum
# WRONG: Only checking if sum equals target
if subtree_sum == target_sum:
return 0
elif subtree_sum < target_sum:
return subtree_sum
else:
return -1
Problem: This doesn't properly handle the case where we need to accumulate values from multiple subtrees before reaching the target sum.
Solution: The correct approach returns 0
when a complete component is found (allowing the parent to "cut" this subtree), returns the accumulated sum when it's less than target (to be combined with sibling subtrees), and returns -1
for invalid cases.
2. Off-by-One Error in Return Value
Many solutions incorrectly return num_components
instead of num_components - 1
:
# WRONG if dfs(0, -1) == 0: return num_components # This returns number of components, not edges deleted! # CORRECT if dfs(0, -1) == 0: return num_components - 1 # Number of edges deleted = components - 1
Problem: The question asks for the number of edges deleted, not the number of components created.
Solution: Remember that deleting k
edges creates k + 1
components, so if we want num_components
components, we need to delete num_components - 1
edges.
3. Inefficient Component Count Enumeration
Starting from k = 2
and going up is inefficient:
# INEFFICIENT
for num_components in range(2, num_nodes + 1):
if total_sum % num_components == 0:
target_sum = total_sum // num_components
if dfs(0, -1) == 0:
return num_components - 1
Problem: This approach finds the minimum number of edges to delete rather than the maximum. Also, it doesn't consider the constraint that each component must have at least one node.
Solution: Start from the maximum possible number of components and work downward. The maximum is bounded by min(n, total_sum // max_value)
since each component needs at least the value of the largest node.
4. Missing Edge Case: Single Node Components
Not considering that the maximum component value constrains the minimum component sum:
# WRONG: Not considering node value constraints
max_components = num_nodes
# CORRECT: Each component must contain at least the max node value
max_components = min(num_nodes, total_sum // max(nums))
Problem: If we have a node with value 10 and total sum is 30, we can have at most 3 components (each with sum 10), not more.
Solution: Calculate the upper bound on components as min(n, total_sum // max(nums))
to ensure each component can accommodate at least the largest node value.
5. Graph Construction Error with Self-Loops
Be careful not to create duplicate edges or self-loops when building the adjacency list:
# POTENTIAL ISSUE if edges contain duplicates or self-loops for node_a, node_b in edges: adjacency_list[node_a].append(node_b) adjacency_list[node_b].append(node_a)
Problem: While the problem guarantees a valid tree (no cycles, n-1 edges for n nodes), some implementations might not handle edge cases properly during testing.
Solution: The current implementation is correct for valid tree input. However, for robustness, you could add validation or use a set-based adjacency list if duplicate edges were possible.
Given a sorted array of integers and an integer called target, find the element that
equals to the target and return its index. Select the correct code that fills the
___
in the given code snippet.
1def binary_search(arr, target):
2 left, right = 0, len(arr) - 1
3 while left ___ right:
4 mid = (left + right) // 2
5 if arr[mid] == target:
6 return mid
7 if arr[mid] < target:
8 ___ = mid + 1
9 else:
10 ___ = mid - 1
11 return -1
12
1public static int binarySearch(int[] arr, int target) {
2 int left = 0;
3 int right = arr.length - 1;
4
5 while (left ___ right) {
6 int mid = left + (right - left) / 2;
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
1function binarySearch(arr, target) {
2 let left = 0;
3 let right = arr.length - 1;
4
5 while (left ___ right) {
6 let mid = left + Math.trunc((right - left) / 2);
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
Recommended Readings
Everything About Trees A tree is a type of graph data structure composed of nodes and edges Its main properties are It is acyclic doesn't contain any cycles There exists a path from the root to any node Has N 1 edges where N is the number of nodes in the tree and
https assets algo monster cover_photos dfs svg Depth First Search Prereqs Recursion Review problems recursion_intro Trees problems tree_intro With a solid understanding of recursion under our belts we are now ready to tackle one of the most useful techniques in coding interviews Depth First Search DFS As the name suggests
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Want a Structured Path to Master System Design Too? Don’t Miss This!