3367. Maximize Sum of Weights after Edge Removals
Problem Description
You are given an undirected tree with n
nodes numbered from 0
to n - 1
. The tree is represented by a 2D array edges
of length n - 1
, where each element edges[i] = [ui, vi, wi]
represents an edge between nodes ui
and vi
with weight wi
.
Your goal is to remove some edges (or none) from the tree such that:
- After removal, each node can be connected to at most
k
other nodes - The sum of weights of the remaining edges is maximized
The task is to find the maximum possible sum of weights that can be achieved after removing edges according to these constraints.
For example, if a node initially has 5 edges connected to it and k = 3
, you must remove at least 2 edges from that node. You want to remove the edges with the smallest weights to keep the total sum as large as possible.
The solution uses dynamic programming on the tree structure. For each node, it calculates two values:
- The maximum sum when this node can use up to
k
edges to its children - The maximum sum when this node can use up to
k - 1
edges to its children (reserving one edge for its parent)
The algorithm performs a depth-first search starting from node 0, computing these values bottom-up. For each node, it greedily selects the most profitable edges (those that add positive value) up to the limit k
or k - 1
, sorting them in descending order by their contribution to the total sum.
The final answer is the maximum of the two values computed for the root node (which has no parent, so both scenarios are valid).
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 describes an undirected tree with nodes and edges. A tree is a special type of graph (connected and acyclic).
Is it a tree?
- Yes: The problem states "There exists an undirected tree with n nodes numbered 0 to n - 1" and we have exactly n-1 edges, which confirms it's a tree structure.
DFS
- We arrive at DFS: Since we're dealing with a tree structure, the flowchart leads us directly to using Depth-First Search.
Conclusion: The flowchart suggests using a DFS (Depth-First Search) approach for this tree problem.
This makes sense because:
- We need to traverse the entire tree to compute optimal solutions
- The problem requires making decisions at each node about which edges to keep (up to k edges per node)
- We need to compute information bottom-up from leaves to root, which is naturally handled by DFS with post-order traversal
- For each subtree rooted at a node, we need to determine the maximum weight sum possible, which requires visiting all descendants first
The DFS approach allows us to:
- Visit each node exactly once
- Compute the optimal solution for each subtree before processing its parent
- Make greedy choices at each node about which child edges to keep based on their contribution to the total weight sum
Intuition
The key insight is that we need to make local decisions at each node about which edges to keep, but these decisions affect the entire tree structure. Since each node can have at most k
edges, we need to choose the most valuable edges at each node.
Think of it this way: imagine you're standing at any node in the tree. You can see all the edges connecting to your neighbors. If you have more than k
neighbors, you must cut some edges. Which ones should you cut? Naturally, you want to keep the edges that contribute the most to your total sum.
But here's the twist - the value of keeping an edge isn't just the edge weight itself. When you keep an edge to a child node, you're also keeping the entire subtree rooted at that child. So the real value of keeping an edge is: edge_weight + optimal_sum_of_child_subtree
.
This leads us to a bottom-up dynamic programming approach using DFS:
- Start from the leaves and work our way up to the root
- At each node, calculate the maximum sum we can get from its subtree
- For each child, we have a choice: include the edge to that child or not
- If we include the edge, we gain:
edge_weight + child_subtree_sum
The clever part is recognizing that each node needs to return two values:
include_parent
: Maximum sum when this node uses at mostk
edges (can connect to parent)exclude_parent
: Maximum sum when this node uses at mostk-1
edges (reserving one edge for parent connection)
Why two values? Because when a parent node is considering whether to keep the edge to this child, it needs to know the child's optimal sum when the child reserves an edge for the parent connection (k-1
case).
At each node, we greedily select the best edges by calculating the "profit" of each edge: edge_weight + child_exclude_parent - child_include_parent
. We sort these profits in descending order and take the top k
(or k-1
) most profitable edges.
The root node is special because it has no parent, so we can use all k
edges for its children. That's why the final answer is the maximum of both values computed for the root.
Learn more about Tree, Depth-First Search and Dynamic Programming patterns.
Solution Approach
The implementation uses a DFS-based dynamic programming approach with the following key components:
1. Graph Representation
First, we build an adjacency list representation of the tree:
g: List[List[Tuple[int, int]]] = [[] for _ in range(n)]
for u, v, w in edges:
g[u].append((v, w))
g[v].append((u, w))
Each node stores a list of tuples (neighbor, weight)
representing its connected edges.
2. DFS Function with Two Return Values
The core of the solution is the dfs(u, fa)
function that returns a tuple (a, b)
:
a
: Maximum sum when nodeu
can use up tok
edges to its childrenb
: Maximum sum when nodeu
can use up tok-1
edges to its children
def dfs(u: int, fa: int) -> Tuple[int, int]:
3. Processing Each Node
For each node u
, we:
- Initialize a base sum
s = 0
(sum without any edges to children) - Create a list
t
to store the profit of each child edge
s = 0 t = [] for v, w in g[u]: if v == fa: # Skip the parent edge continue a, b = dfs(v, u) # Recursively process child s += a # Add child's contribution without the connecting edge
4. Calculating Edge Profits
For each child v
with edge weight w
:
a
= child's max sum using up tok
edges (not including parent edge)b
= child's max sum using up tok-1
edges (reserving for parent edge)- Profit of including this edge =
w + b - a
if (d := (w + b - a)) > 0: t.append(d)
We only store positive profits because keeping an edge with negative profit would decrease our total sum.
5. Greedy Selection
Sort profits in descending order and greedily select the best edges:
t.sort(reverse=True)
return s + sum(t[:k]), s + sum(t[:k-1])
- For the first return value: take up to
k
best edges - For the second return value: take up to
k-1
best edges (reserving one for parent)
6. Final Answer
Start DFS from node 0 (arbitrary root) with parent -1
:
x, y = dfs(0, -1)
return max(x, y)
Since the root has no parent, both scenarios (using k
edges or k-1
edges) are valid, so we take the maximum.
Time Complexity: O(n log n)
where n
is the number of nodes. We visit each node once, and at each node, we sort its children's profits.
Space Complexity: O(n)
for the adjacency list and recursion stack.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example to illustrate the solution approach.
Example: Consider a tree with 4 nodes and k = 2
:
edges = [[0, 1, 10], [0, 2, 15], [1, 3, 20]]
This creates the following tree:
0 / \ 10/ \15 / \ 1 2 | 20| | 3
Each node can have at most k = 2
edges. Let's trace through the DFS:
Step 1: DFS reaches leaf node 3
- Node 3 has only 1 edge (to parent 1)
- No children to process
- Returns
(0, 0)
- no edges to children in either case
Step 2: DFS backtracks to node 1
- Node 1 has 2 edges: to parent 0 and child 3
- Process child 3:
dfs(3, 1)
returns(0, 0)
- Calculate profit of edge (1,3):
20 + 0 - 0 = 20
- Profit list
t = [20]
- Returns:
- Using k=2 edges:
0 + sum([20]) = 20
- Using k-1=1 edge:
0 + sum([20]) = 20
- Using k=2 edges:
- Returns
(20, 20)
Step 3: DFS reaches leaf node 2
- Node 2 has only 1 edge (to parent 0)
- No children to process
- Returns
(0, 0)
Step 4: DFS backtracks to root node 0
- Node 0 has 2 edges: to children 1 and 2
- Process child 1:
dfs(1, 0)
returns(20, 20)
- Base sum without edge:
s = 20
- Profit of edge (0,1):
10 + 20 - 20 = 10
- Base sum without edge:
- Process child 2:
dfs(2, 0)
returns(0, 0)
- Update base sum:
s = 20 + 0 = 20
- Profit of edge (0,2):
15 + 0 - 0 = 15
- Update base sum:
- Profit list
t = [10, 15]
, sorted descending:[15, 10]
- Returns:
- Using k=2 edges:
20 + sum([15, 10]) = 45
- Using k-1=1 edge:
20 + sum([15]) = 35
- Using k=2 edges:
Final Answer: max(45, 35) = 45
The optimal solution keeps all edges since node 0 has exactly 2 children (⤠k), node 1 has 2 edges total (⤠k), and leaf nodes have only 1 edge each.
Key Observations:
- At node 1, the profit of keeping edge (1,3) is positive (20), so we include it
- At node 0, both child edges have positive profit, and since we can keep k=2 edges, we keep both
- The base sum at each node accumulates the "no edge" scenario, then we add back profitable edges
- The algorithm naturally handles the constraint by limiting selections to k or k-1 edges at each step
Solution Implementation
1class Solution:
2 def maximizeSumOfWeights(self, edges: List[List[int]], k: int) -> int:
3 """
4 Maximize the sum of weights in a tree by selecting at most k edges per node.
5
6 Args:
7 edges: List of [u, v, weight] representing tree edges
8 k: Maximum number of edges that can be selected per node
9
10 Returns:
11 Maximum sum of weights achievable
12 """
13
14 def dfs(current_node: int, parent_node: int) -> Tuple[int, int]:
15 """
16 Perform DFS to calculate maximum weights.
17
18 Args:
19 current_node: Current node being processed
20 parent_node: Parent of current node (-1 if root)
21
22 Returns:
23 Tuple of (max_sum_with_k_edges, max_sum_with_k_minus_1_edges)
24 - First value: max sum when current node can use k edges
25 - Second value: max sum when current node can use k-1 edges (parent edge used)
26 """
27
28 # Base sum without including any edges from current node
29 base_sum = 0
30
31 # Store potential gains from including edges to children
32 edge_gains = []
33
34 # Process all neighbors (children in the DFS tree)
35 for neighbor, edge_weight in adjacency_list[current_node]:
36 # Skip the parent edge to avoid revisiting
37 if neighbor == parent_node:
38 continue
39
40 # Recursively get the maximum sums for the subtree rooted at neighbor
41 sum_with_k, sum_with_k_minus_1 = dfs(neighbor, current_node)
42
43 # Add the best sum without considering the edge to this child
44 base_sum += sum_with_k
45
46 # Calculate the gain from including the edge to this child
47 # gain = (edge_weight + child's sum with k-1 edges) - (child's sum with k edges)
48 gain = edge_weight + sum_with_k_minus_1 - sum_with_k
49
50 # Only store positive gains (edges worth including)
51 if gain > 0:
52 edge_gains.append(gain)
53
54 # Sort gains in descending order to greedily select the best edges
55 edge_gains.sort(reverse=True)
56
57 # Calculate maximum sums:
58 # 1. When we can use k edges from current node
59 max_sum_k_edges = base_sum + sum(edge_gains[:k])
60
61 # 2. When we can use k-1 edges (one slot reserved for parent edge)
62 max_sum_k_minus_1_edges = base_sum + sum(edge_gains[:k - 1])
63
64 return max_sum_k_edges, max_sum_k_minus_1_edges
65
66 # Calculate number of nodes (tree has n-1 edges for n nodes)
67 num_nodes = len(edges) + 1
68
69 # Build adjacency list representation of the tree
70 adjacency_list: List[List[Tuple[int, int]]] = [[] for _ in range(num_nodes)]
71 for node_u, node_v, weight in edges:
72 adjacency_list[node_u].append((node_v, weight))
73 adjacency_list[node_v].append((node_u, weight))
74
75 # Start DFS from node 0 as root (parent = -1)
76 max_with_k, max_with_k_minus_1 = dfs(0, -1)
77
78 # Return the maximum of both possibilities
79 return max(max_with_k, max_with_k_minus_1)
80
1class Solution {
2 // Adjacency list representation of the tree
3 private List<int[]>[] adjacencyList;
4 // Maximum number of edges that can be selected per node
5 private int maxEdgesPerNode;
6
7 public long maximizeSumOfWeights(int[][] edges, int k) {
8 this.maxEdgesPerNode = k;
9 int numberOfNodes = edges.length + 1;
10
11 // Initialize adjacency list for the tree
12 adjacencyList = new List[numberOfNodes];
13 Arrays.setAll(adjacencyList, i -> new ArrayList<>());
14
15 // Build undirected tree from edges
16 for (int[] edge : edges) {
17 int nodeU = edge[0];
18 int nodeV = edge[1];
19 int weight = edge[2];
20 adjacencyList[nodeU].add(new int[] {nodeV, weight});
21 adjacencyList[nodeV].add(new int[] {nodeU, weight});
22 }
23
24 // Start DFS from node 0 with no parent (-1)
25 long[] result = dfs(0, -1);
26
27 // Return maximum between including edge to parent and not including it
28 return Math.max(result[0], result[1]);
29 }
30
31 /**
32 * DFS to calculate maximum weight sum for subtree rooted at current node
33 * @param currentNode - current node being processed
34 * @param parentNode - parent of current node (-1 if root)
35 * @return array where:
36 * [0] = max sum when edge to parent can be included
37 * [1] = max sum when edge to parent must be excluded
38 */
39 private long[] dfs(int currentNode, int parentNode) {
40 // Base sum for current subtree
41 long baseSum = 0;
42 // List to store potential gains from including edges to children
43 List<Long> edgeGains = new ArrayList<>();
44
45 // Process all neighbors (children in the tree)
46 for (int[] edge : adjacencyList[currentNode]) {
47 int childNode = edge[0];
48 int edgeWeight = edge[1];
49
50 // Skip parent node to avoid cycles
51 if (childNode == parentNode) {
52 continue;
53 }
54
55 // Recursively calculate values for child subtree
56 long[] childResult = dfs(childNode, currentNode);
57
58 // Add the minimum guaranteed sum from child
59 baseSum += childResult[0];
60
61 // Calculate gain from including edge to this child
62 long gain = edgeWeight + childResult[1] - childResult[0];
63
64 // Only consider positive gains
65 if (gain > 0) {
66 edgeGains.add(gain);
67 }
68 }
69
70 // Sort gains in descending order to greedily select best edges
71 edgeGains.sort(Comparator.reverseOrder());
72
73 // Add top (k-1) gains when parent edge can be included
74 for (int i = 0; i < Math.min(edgeGains.size(), maxEdgesPerNode - 1); i++) {
75 baseSum += edgeGains.get(i);
76 }
77
78 // Calculate two scenarios:
79 // sumWithParentOption: can potentially include edge to parent (uses k-1 child edges)
80 // sumWithoutParent: must exclude edge to parent (can use k child edges)
81 long sumWithParentOption = baseSum + (edgeGains.size() >= maxEdgesPerNode ?
82 edgeGains.get(maxEdgesPerNode - 1) : 0);
83 long sumWithoutParent = baseSum;
84
85 return new long[] {sumWithParentOption, sumWithoutParent};
86 }
87}
88
1class Solution {
2public:
3 long long maximizeSumOfWeights(vector<vector<int>>& edges, int k) {
4 // Build adjacency list for the tree (n nodes, n-1 edges)
5 int n = edges.size() + 1;
6 vector<vector<pair<int, int>>> adjacencyList(n);
7
8 // Create bidirectional edges with weights
9 for (auto& edge : edges) {
10 int node1 = edge[0];
11 int node2 = edge[1];
12 int weight = edge[2];
13 adjacencyList[node1].emplace_back(node2, weight);
14 adjacencyList[node2].emplace_back(node1, weight);
15 }
16
17 using ll = long long;
18
19 // DFS function returns a pair:
20 // - first: max sum when current node can take up to k edges
21 // - second: max sum when current node can take up to k-1 edges (parent edge not counted)
22 auto dfs = [&](this auto&& dfs, int currentNode, int parentNode) -> pair<ll, ll> {
23 ll baseSum = 0; // Sum of choosing subtrees without parent edges
24 vector<ll> gains; // Gains from choosing edges to children
25
26 // Process all children
27 for (auto& [childNode, edgeWeight] : adjacencyList[currentNode]) {
28 if (childNode == parentNode) {
29 continue; // Skip parent edge
30 }
31
32 // Recursively get results for child subtree
33 auto [withKEdges, withKMinus1Edges] = dfs(childNode, currentNode);
34
35 // By default, take the result without using the edge to child
36 baseSum += withKEdges;
37
38 // Calculate gain if we use the edge to this child
39 ll gain = edgeWeight + withKMinus1Edges - withKEdges;
40 if (gain > 0) {
41 gains.push_back(gain);
42 }
43 }
44
45 // Sort gains in descending order to greedily pick best edges
46 ranges::sort(gains, greater<>());
47
48 // Add top k-1 gains to base sum (for second return value)
49 ll sumWithKMinus1Edges = baseSum;
50 for (int i = 0; i < min((int)gains.size(), k - 1); ++i) {
51 sumWithKMinus1Edges += gains[i];
52 }
53
54 // For first return value, we can use one more edge (the kth best)
55 ll sumWithKEdges = sumWithKMinus1Edges;
56 if (gains.size() >= k) {
57 sumWithKEdges += gains[k - 1];
58 }
59
60 return {sumWithKEdges, sumWithKMinus1Edges};
61 };
62
63 // Start DFS from node 0 as root (no parent, so parent = -1)
64 auto [resultWithK, resultWithKMinus1] = dfs(0, -1);
65
66 // Return the maximum of both possibilities
67 return max(resultWithK, resultWithKMinus1);
68 }
69};
70
1/**
2 * Maximizes the sum of weights in a tree with constraint k
3 * @param edges - Array of edges where each edge is [u, v, weight]
4 * @param k - Maximum number of edges that can be selected from each node's children
5 * @returns Maximum sum of weights achievable
6 */
7function maximizeSumOfWeights(edges: number[][], k: number): number {
8 const nodeCount: number = edges.length + 1;
9
10 // Build adjacency list representation of the tree
11 // Each node maps to an array of [neighbor, weight] pairs
12 const adjacencyList: [number, number][][] = Array.from(
13 { length: nodeCount },
14 () => []
15 );
16
17 // Populate adjacency list with bidirectional edges
18 for (const [nodeU, nodeV, weight] of edges) {
19 adjacencyList[nodeU].push([nodeV, weight]);
20 adjacencyList[nodeV].push([nodeU, weight]);
21 }
22
23 /**
24 * DFS to calculate maximum weight sums for subtree rooted at current node
25 * @param currentNode - Current node being processed
26 * @param parentNode - Parent of current node (-1 if root)
27 * @returns Tuple of [maxSumWithKEdges, maxSumWithKMinus1Edges]
28 */
29 const dfs = (currentNode: number, parentNode: number): [number, number] => {
30 // Base sum from all children without including edge weights
31 let baseSum: number = 0;
32
33 // Store potential gains from including each child edge
34 const edgeGains: number[] = [];
35
36 // Process all children of current node
37 for (const [childNode, edgeWeight] of adjacencyList[currentNode]) {
38 // Skip parent edge to avoid cycles
39 if (childNode === parentNode) continue;
40
41 // Recursively calculate values for child subtree
42 const [childMaxWithK, childMaxWithKMinus1] = dfs(childNode, currentNode);
43
44 // Add child's contribution without the connecting edge
45 baseSum += childMaxWithK;
46
47 // Calculate gain from including the edge to this child
48 // Gain = (edge weight + child's K-1 solution) - (child's K solution)
49 const gain: number = edgeWeight + childMaxWithKMinus1 - childMaxWithK;
50
51 // Only store positive gains
52 if (gain > 0) {
53 edgeGains.push(gain);
54 }
55 }
56
57 // Sort gains in descending order to greedily select best edges
58 edgeGains.sort((a: number, b: number) => b - a);
59
60 // Calculate sum when selecting up to k-1 edges (for parent edge inclusion)
61 for (let i = 0; i < Math.min(edgeGains.length, k - 1); i++) {
62 baseSum += edgeGains[i];
63 }
64
65 // Store the k-1 edges sum for parent's calculation
66 const sumWithKMinus1Edges: number = baseSum;
67
68 // Calculate sum when selecting up to k edges (when no parent edge selected)
69 if (edgeGains.length >= k) {
70 baseSum += edgeGains[k - 1];
71 }
72
73 const sumWithKEdges: number = baseSum;
74
75 return [sumWithKEdges, sumWithKMinus1Edges];
76 };
77
78 // Start DFS from root node (0) with no parent (-1)
79 const [maxWithK, maxWithKMinus1] = dfs(0, -1);
80
81 // Return the maximum achievable sum
82 return Math.max(maxWithK, maxWithKMinus1);
83}
84
Time and Space Complexity
Time Complexity: O(n log n)
The algorithm performs a depth-first search (DFS) traversal of the tree:
- The DFS visits each node exactly once, contributing
O(n)
to traverse the tree - At each node
u
, we iterate through all its adjacent edges, which across all nodes totalsO(n-1)
edge traversals (since there aren-1
edges in a tree) - For each node, we collect positive differences
d = w + b - a
in listt
and sort them in descending order - In the worst case, a node could have up to
n-1
children, making the sorting operationO(n log n)
- Since sorting dominates the complexity at each node and we have
n
nodes, the overall time complexity isO(n log n)
Space Complexity: O(n)
The space usage consists of:
- The adjacency list
g
stores all edges twice (once for each direction), usingO(n)
space - The recursion stack for DFS can go up to
O(n)
depth in the worst case (skewed tree) - At each recursive call, list
t
stores at most the number of children for that node, which across all recursive calls simultaneously can totalO(n)
space - The sorting operation uses
O(log n)
auxiliary space in Python's Timsort implementation - Overall space complexity is
O(n)
as the adjacency list and recursion stack dominate
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrectly Handling the Edge Count Constraint
Pitfall: A common mistake is misunderstanding what "at most k edges" means. Some might interpret this as k edges in total across the entire tree, rather than k edges per node.
Example of Wrong Thinking:
# WRONG: Trying to limit total edges globally
def wrong_approach(edges, k):
# Sort all edges by weight and take top k
edges.sort(key=lambda x: x[2], reverse=True)
return sum(edge[2] for edge in edges[:k])
Solution: Remember that the constraint applies to each node individually. Each node can have at most k edges connected to it after removal.
2. Forgetting to Account for Bidirectional Edges
Pitfall: When building the adjacency list, forgetting that the tree is undirected and each edge should be added in both directions.
Wrong Implementation:
# WRONG: Only adding edge in one direction for u, v, w in edges: g[u].append((v, w)) # Missing: g[v].append((u, w))
Solution: Always add edges in both directions for undirected graphs:
for u, v, w in edges: g[u].append((v, w)) g[v].append((u, w))
3. Not Handling the Parent Edge Correctly in DFS
Pitfall: The most subtle pitfall is incorrectly handling the parent edge case. When a node uses k-1 edges for its children, it's reserving one slot for its parent edge. However, this parent edge has already been accounted for in the parent's calculation.
Wrong Thinking:
# WRONG: Trying to add parent edge weight again
def dfs(u, fa, parent_weight):
# ... calculate for children ...
return max_sum_k + parent_weight, max_sum_k_minus_1 + parent_weight # WRONG!
Solution: The parent edge weight is already included when the parent node makes its decision. The child only needs to reserve a slot (use k-1 instead of k edges to children) but doesn't add the parent edge weight again.
4. Incorrect Profit Calculation
Pitfall: Misunderstanding what "profit" means when deciding whether to include an edge to a child.
Wrong Calculation:
# WRONG: Just using edge weight as profit profit = w # This ignores the child's contribution
Correct Calculation:
# CORRECT: Profit = gain from including edge vs not including it profit = (w + child_sum_with_k_minus_1) - child_sum_with_k
The profit represents the difference between:
- Including the edge (weight w + child uses k-1 edges)
- Not including the edge (child uses k edges)
5. Including Negative or Zero Profit Edges
Pitfall: Including all edges to children regardless of their profit value.
Wrong Implementation:
# WRONG: Including all edges even if they decrease total sum for v, w in g[u]: if v != fa: a, b = dfs(v, u) t.append(w + b - a) # Might be negative!
Solution: Only include edges with positive profit:
for v, w in g[u]: if v != fa: a, b = dfs(v, u) profit = w + b - a if profit > 0: # Only positive profits t.append(profit)
6. Off-by-One Error with Number of Nodes
Pitfall: Incorrectly calculating the number of nodes from the edges array.
Wrong:
# WRONG: Using len(edges) as number of nodes
n = len(edges) # This gives n-1, not n
Correct:
# CORRECT: A tree with n nodes has n-1 edges
n = len(edges) + 1
7. Not Considering Both Cases for the Root Node
Pitfall: Only returning one value for the root instead of taking the maximum of both possibilities.
Wrong:
# WRONG: Only considering one case x, _ = dfs(0, -1) return x
Correct:
# CORRECT: Root has no parent, so both cases are valid
x, y = dfs(0, -1)
return max(x, y)
The root node is special because it has no parent edge to reserve a slot for, so both the k-edge and (k-1)-edge scenarios are valid final configurations.
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
What is Dynamic Programming Prerequisite DFS problems dfs_intro Backtracking problems backtracking Memoization problems memoization_intro Pruning problems backtracking_pruning Dynamic programming is an algorithmic optimization technique that breaks down a complicated problem into smaller overlapping sub problems in a recursive manner and uses solutions to the sub problems to construct a solution
Want a Structured Path to Master System Design Too? Donât Miss This!