Facebook Pixel

2281. Sum of Total Strength of Wizards

Problem Description

You are given an array strength where strength[i] represents the strength of the i-th wizard in your kingdom.

For any contiguous subarray of wizards, the total strength is calculated as:

  • The minimum strength among all wizards in the subarray
  • Multiplied by the sum of all strengths in the subarray

For example, if you have a subarray [3, 1, 5]:

  • The weakest wizard has strength 1
  • The sum of all strengths is 3 + 1 + 5 = 9
  • The total strength is 1 × 9 = 9

Your task is to find the sum of total strengths for all possible contiguous subarrays in the given array.

Since the result can be very large, return the answer modulo 10^9 + 7.

Example walkthrough:

If strength = [1, 3, 2], the contiguous subarrays and their total strengths are:

  • [1]: min = 1, sum = 1, total strength = 1 × 1 = 1
  • [3]: min = 3, sum = 3, total strength = 3 × 3 = 9
  • [2]: min = 2, sum = 2, total strength = 2 × 2 = 4
  • [1, 3]: min = 1, sum = 4, total strength = 1 × 4 = 4
  • [3, 2]: min = 2, sum = 5, total strength = 2 × 5 = 10
  • [1, 3, 2]: min = 1, sum = 6, total strength = 1 × 6 = 6

The sum of all total strengths = 1 + 9 + 4 + 4 + 10 + 6 = 34

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The brute force approach would be to check every possible subarray, find its minimum element and sum, then calculate the total strength. This would take O(n^3) time, which is too slow for large arrays.

The key insight is to think about the problem from a different angle: instead of iterating through all subarrays, we can focus on each element and ask - "In how many subarrays is this element the minimum?"

For each element strength[i], if we know all the subarrays where it acts as the minimum element, we can calculate its contribution to the final answer. The contribution would be: strength[i] × (sum of all subarray sums where strength[i] is the minimum)

To find which subarrays have strength[i] as their minimum, we need to find:

  • The nearest smaller element to the left (let's call its index left[i])
  • The nearest smaller or equal element to the right (let's call its index right[i])

Any subarray that includes strength[i] and spans from index l (where left[i] < l <= i) to index r (where i <= r < right[i]) will have strength[i] as its minimum element.

The next challenge is efficiently calculating the sum of all subarray sums that include strength[i] as the minimum. This is where prefix sums come in handy. By using a double prefix sum (prefix sum of prefix sums), we can calculate in O(1) time:

  • The sum of all subarray sums that start from any position between left[i]+1 to i and end at any position between i to right[i]-1

The monotonic stack technique helps us efficiently find the nearest smaller elements on both sides in O(n) time. We use the stack to maintain elements in increasing order, popping elements when we find a smaller one.

This approach reduces the overall time complexity to O(n), making it efficient even for large arrays.

Learn more about Stack, Prefix Sum and Monotonic Stack patterns.

Solution Approach

The solution implements the intuition using monotonic stacks and prefix sums. Let's walk through each component:

Step 1: Find boundaries using monotonic stacks

First, we find for each element the range where it acts as the minimum:

left = [-1] * n  # nearest smaller element to the left
right = [n] * n   # nearest smaller or equal element to the right

For the left boundaries:

  • Iterate through the array from left to right
  • Maintain a stack of indices in increasing order of their values
  • When we encounter strength[i], pop all elements from the stack that are >= strength[i]
  • The top of the stack (if exists) gives us left[i]

For the right boundaries:

  • Iterate through the array from right to left
  • Similar process, but we pop elements that are > strength[i] (strictly greater)
  • This ensures we handle equal elements correctly (leftmost one is chosen as minimum)

Step 2: Calculate prefix sums of prefix sums

ss = list(accumulate(list(accumulate(strength, initial=0)), initial=0))

This creates a double prefix sum array where:

  • First accumulate gives us regular prefix sums: ps[i] = strength[0] + ... + strength[i-1]
  • Second accumulate gives us prefix sums of prefix sums: ss[i] = ps[0] + ps[1] + ... + ps[i-1]

Step 3: Calculate contribution of each element

For each element at index i with value v:

  • It's the minimum in all subarrays from [l, r] where l ∈ [left[i]+1, i] and r ∈ [i, right[i]-1]

The sum of all subarray sums where strength[i] is minimum can be calculated as:

a = (ss[r + 2] - ss[i + 1]) * (i - l + 1)  # sum of subarrays ending after i
b = (ss[i + 1] - ss[l]) * (r - i + 1)      # sum of subarrays starting before i
total_sum = a - b

This formula uses the double prefix sum to efficiently compute:

  • a: Sum of all subarrays that end at positions from i to r, multiplied by the number of possible starting positions
  • b: Sum of all subarrays that start at positions from l to i, multiplied by the number of possible ending positions

The contribution of element i is then: (a - b) * v

Step 4: Sum all contributions

ans = (ans + (a - b) * v) % mod

We add each element's contribution to the final answer, taking modulo at each step to prevent overflow.

The time complexity is O(n) as we make a constant number of passes through the array, and space complexity is O(n) for the auxiliary arrays.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution approach with strength = [2, 1, 3].

Step 1: Find boundaries using monotonic stacks

Finding left[] (nearest smaller element to the left):

  • i=0, strength[0]=2: stack is empty, so left[0]=-1. Push 0 to stack. Stack: [0]
  • i=1, strength[1]=1: Pop 0 (since 2≥1). Stack empty, so left[1]=-1. Push 1. Stack: [1]
  • i=2, strength[2]=3: 1<3, so left[2]=1. Push 2. Stack: [1,2]
  • Result: left = [-1, -1, 1]

Finding right[] (nearest smaller or equal to the right):

  • i=2, strength[2]=3: stack empty, so right[2]=3. Push 2. Stack: [2]
  • i=1, strength[1]=1: Pop 2 (since 3>1). Stack empty, so right[1]=3. Push 1. Stack: [1]
  • i=0, strength[0]=2: 1<2, so right[0]=1. Push 0. Stack: [1,0]
  • Result: right = [1, 3, 3]

Step 2: Calculate prefix sums of prefix sums

  • Original: [2, 1, 3]
  • First prefix sum: [0, 2, 3, 6] (ps[i] = sum of elements before index i)
  • Second prefix sum: [0, 0, 2, 5, 11] (ss[i] = sum of ps[0] to ps[i-1])

Step 3: Calculate contribution of each element

For element at index 0 (value=2):

  • It's minimum in subarrays from [l=0, r=0] (since left[0]=-1, right[0]=1)
  • l = left[0]+1 = 0, r = right[0]-1 = 0
  • a = (ss[0+2] - ss[0+1]) × (0-0+1) = (2-0) × 1 = 2
  • b = (ss[0+1] - ss[0]) × (0-0+1) = (0-0) × 1 = 0
  • Contribution = (2-0) × 2 = 4

For element at index 1 (value=1):

  • It's minimum in subarrays from [l=0, r=2] (since left[1]=-1, right[1]=3)
  • l = left[1]+1 = 0, r = right[1]-1 = 2
  • a = (ss[2+2] - ss[1+1]) × (1-0+1) = (11-2) × 2 = 18
  • b = (ss[1+1] - ss[0]) × (2-1+1) = (2-0) × 2 = 4
  • Contribution = (18-4) × 1 = 14

For element at index 2 (value=3):

  • It's minimum in subarrays from [l=2, r=2] (since left[2]=1, right[2]=3)
  • l = left[2]+1 = 2, r = right[2]-1 = 2
  • a = (ss[2+2] - ss[2+1]) × (2-2+1) = (11-5) × 1 = 6
  • b = (ss[2+1] - ss[2]) × (2-2+1) = (5-2) × 1 = 3
  • Contribution = (6-3) × 3 = 9

Step 4: Sum all contributions Total = 4 + 14 + 9 = 27

Let's verify:

  • [2]: min=2, sum=2, strength=2×2=4 ✓
  • [1]: min=1, sum=1, strength=1×1=1
  • [3]: min=3, sum=3, strength=3×3=9 ✓
  • [2,1]: min=1, sum=3, strength=1×3=3
  • [1,3]: min=1, sum=4, strength=1×4=4
  • [2,1,3]: min=1, sum=6, strength=1×6=6

Total = 4+1+9+3+4+6 = 27 ✓

Solution Implementation

1class Solution:
2    def totalStrength(self, strength: List[int]) -> int:
3        """
4        Calculate the sum of total strength across all subarrays.
5        For each subarray, total strength = min(subarray) * sum(subarray)
6        """
7        n = len(strength)
8      
9        # Find the previous smaller element for each position
10        # left[i] = index of the nearest element to the left that is strictly smaller than strength[i]
11        # -1 if no such element exists
12        left_smaller = [-1] * n
13        stack = []
14      
15        for i, current_strength in enumerate(strength):
16            # Pop elements that are greater than or equal to current
17            while stack and strength[stack[-1]] >= current_strength:
18                stack.pop()
19          
20            if stack:
21                left_smaller[i] = stack[-1]
22            stack.append(i)
23      
24        # Find the next smaller or equal element for each position
25        # right[i] = index of the nearest element to the right that is smaller than or equal to strength[i]
26        # n if no such element exists
27        right_smaller = [n] * n
28        stack = []
29      
30        for i in range(n - 1, -1, -1):
31            # Pop elements that are strictly greater than current
32            while stack and strength[stack[-1]] > strength[i]:
33                stack.pop()
34          
35            if stack:
36                right_smaller[i] = stack[-1]
37            stack.append(i)
38      
39        # Build prefix sum array and prefix sum of prefix sums
40        # This helps calculate range sums efficiently
41        # prefix_sum_of_prefix_sums[i] = sum of all prefix sums up to index i-1
42        prefix_sum_of_prefix_sums = list(accumulate(list(accumulate(strength, initial=0)), initial=0))
43      
44        MOD = 10**9 + 7
45        total_strength_sum = 0
46      
47        # For each element as the minimum of subarrays
48        for i, min_strength in enumerate(strength):
49            # Range where strength[i] is the minimum
50            # All subarrays from index left_bound to right_bound that include i
51            left_bound = left_smaller[i] + 1
52            right_bound = right_smaller[i] - 1
53          
54            # Calculate contribution of all subarrays where strength[i] is minimum
55            # Using the formula for sum of subarray sums
56          
57            # Sum of all subarrays ending after i and starting at or before i
58            positive_contribution = (prefix_sum_of_prefix_sums[right_bound + 2] - prefix_sum_of_prefix_sums[i + 1]) * (i - left_bound + 1)
59          
60            # Sum of all subarrays starting before i and ending at or before i
61            negative_contribution = (prefix_sum_of_prefix_sums[i + 1] - prefix_sum_of_prefix_sums[left_bound]) * (right_bound - i + 1)
62          
63            # Add the contribution of this element as minimum
64            contribution = (positive_contribution - negative_contribution) * min_strength
65            total_strength_sum = (total_strength_sum + contribution) % MOD
66      
67        return total_strength_sum
68
1class Solution {
2    public int totalStrength(int[] strength) {
3        int n = strength.length;
4      
5        // Find the previous smaller element for each position
6        // leftBoundary[i] = index of the previous element < strength[i], or -1 if none exists
7        int[] leftBoundary = new int[n];
8        Arrays.fill(leftBoundary, -1);
9      
10        // Find the next smaller or equal element for each position  
11        // rightBoundary[i] = index of the next element <= strength[i], or n if none exists
12        int[] rightBoundary = new int[n];
13        Arrays.fill(rightBoundary, n);
14      
15        // Use monotonic stack to find previous smaller elements
16        Deque<Integer> monotonicStack = new ArrayDeque<>();
17        for (int i = 0; i < n; ++i) {
18            // Pop elements that are greater than or equal to current element
19            while (!monotonicStack.isEmpty() && strength[monotonicStack.peek()] >= strength[i]) {
20                monotonicStack.pop();
21            }
22            // The remaining top element (if exists) is the previous smaller element
23            if (!monotonicStack.isEmpty()) {
24                leftBoundary[i] = monotonicStack.peek();
25            }
26            monotonicStack.push(i);
27        }
28      
29        // Clear stack for reuse
30        monotonicStack.clear();
31      
32        // Use monotonic stack to find next smaller or equal elements (traverse from right)
33        for (int i = n - 1; i >= 0; --i) {
34            // Pop elements that are strictly greater than current element
35            while (!monotonicStack.isEmpty() && strength[monotonicStack.peek()] > strength[i]) {
36                monotonicStack.pop();
37            }
38            // The remaining top element (if exists) is the next smaller or equal element
39            if (!monotonicStack.isEmpty()) {
40                rightBoundary[i] = monotonicStack.peek();
41            }
42            monotonicStack.push(i);
43        }
44      
45        // Define modulo for avoiding overflow
46        int MOD = (int) 1e9 + 7;
47      
48        // Build prefix sum array
49        // prefixSum[i] = sum of strength[0] to strength[i-1]
50        int[] prefixSum = new int[n + 1];
51        for (int i = 0; i < n; ++i) {
52            prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
53        }
54      
55        // Build prefix sum of prefix sums
56        // prefixSumOfSums[i] = sum of prefixSum[0] to prefixSum[i-1]
57        int[] prefixSumOfSums = new int[n + 2];
58        for (int i = 0; i < n + 1; ++i) {
59            prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
60        }
61      
62        // Calculate the total strength
63        long totalResult = 0;
64      
65        for (int i = 0; i < n; ++i) {
66            int currentValue = strength[i];
67            // Range where strength[i] is the minimum element
68            int leftIndex = leftBoundary[i] + 1;
69            int rightIndex = rightBoundary[i] - 1;
70          
71            // Calculate contribution of all subarrays where strength[i] is minimum
72            // For subarrays ending at or after i
73            long rightContribution = (long) (i - leftIndex + 1) * (prefixSumOfSums[rightIndex + 2] - prefixSumOfSums[i + 1]);
74            // For subarrays ending before i
75            long leftContribution = (long) (rightIndex - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIndex]);
76          
77            // Add the contribution of current element as minimum
78            totalResult = (totalResult + currentValue * ((rightContribution - leftContribution) % MOD)) % MOD;
79        }
80      
81        // Handle negative modulo result
82        return (int) (totalResult + MOD) % MOD;
83    }
84}
85
1class Solution {
2public:
3    int totalStrength(vector<int>& strength) {
4        int n = strength.size();
5        const int MOD = 1e9 + 7;
6      
7        // Find the previous smaller element for each position
8        // leftBound[i] = index of the previous element smaller than strength[i]
9        vector<int> leftBound(n, -1);
10        stack<int> monoStack;
11      
12        for (int i = 0; i < n; ++i) {
13            // Pop elements that are greater than or equal to current element
14            while (!monoStack.empty() && strength[monoStack.top()] >= strength[i]) {
15                monoStack.pop();
16            }
17            if (!monoStack.empty()) {
18                leftBound[i] = monoStack.top();
19            }
20            monoStack.push(i);
21        }
22      
23        // Find the next smaller or equal element for each position
24        // rightBound[i] = index of the next element smaller or equal to strength[i]
25        vector<int> rightBound(n, n);
26        monoStack = stack<int>();  // Reset the stack
27      
28        for (int i = n - 1; i >= 0; --i) {
29            // Pop elements that are strictly greater than current element
30            while (!monoStack.empty() && strength[monoStack.top()] > strength[i]) {
31                monoStack.pop();
32            }
33            if (!monoStack.empty()) {
34                rightBound[i] = monoStack.top();
35            }
36            monoStack.push(i);
37        }
38      
39        // Build prefix sum array: prefixSum[i+1] = sum of strength[0..i]
40        vector<int> prefixSum(n + 1, 0);
41        for (int i = 0; i < n; ++i) {
42            prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
43        }
44      
45        // Build prefix sum of prefix sums: prefixSumOfSums[i+1] = sum of prefixSum[0..i]
46        vector<int> prefixSumOfSums(n + 2, 0);
47        for (int i = 0; i <= n; ++i) {
48            prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
49        }
50      
51        // Calculate the total strength
52        int totalResult = 0;
53      
54        for (int i = 0; i < n; ++i) {
55            int minValue = strength[i];
56            int leftIdx = leftBound[i] + 1;   // Left boundary of subarrays where strength[i] is minimum
57            int rightIdx = rightBound[i] - 1;  // Right boundary of subarrays where strength[i] is minimum
58          
59            // Calculate contribution of all subarrays where strength[i] is the minimum
60            // leftContribution: sum of all subarrays ending at or after position i
61            long leftContribution = (long)(i - leftIdx + 1) * (prefixSumOfSums[rightIdx + 2] - prefixSumOfSums[i + 1]);
62          
63            // rightContribution: sum of all subarrays ending before position i
64            long rightContribution = (long)(rightIdx - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIdx]);
65          
66            // Add the contribution of strength[i] as minimum element
67            totalResult = (totalResult + minValue * ((leftContribution - rightContribution) % MOD)) % MOD;
68        }
69      
70        // Handle negative modulo result
71        return (totalResult + MOD) % MOD;
72    }
73};
74
1function totalStrength(strength: number[]): number {
2    const n = strength.length;
3    const MOD = 1e9 + 7;
4  
5    // Find the previous smaller element for each position
6    // leftBound[i] = index of the previous element smaller than strength[i]
7    const leftBound: number[] = new Array(n).fill(-1);
8    let monoStack: number[] = [];
9  
10    for (let i = 0; i < n; i++) {
11        // Pop elements that are greater than or equal to current element
12        while (monoStack.length > 0 && strength[monoStack[monoStack.length - 1]] >= strength[i]) {
13            monoStack.pop();
14        }
15        if (monoStack.length > 0) {
16            leftBound[i] = monoStack[monoStack.length - 1];
17        }
18        monoStack.push(i);
19    }
20  
21    // Find the next smaller or equal element for each position
22    // rightBound[i] = index of the next element smaller or equal to strength[i]
23    const rightBound: number[] = new Array(n).fill(n);
24    monoStack = []; // Reset the stack
25  
26    for (let i = n - 1; i >= 0; i--) {
27        // Pop elements that are strictly greater than current element
28        while (monoStack.length > 0 && strength[monoStack[monoStack.length - 1]] > strength[i]) {
29            monoStack.pop();
30        }
31        if (monoStack.length > 0) {
32            rightBound[i] = monoStack[monoStack.length - 1];
33        }
34        monoStack.push(i);
35    }
36  
37    // Build prefix sum array: prefixSum[i+1] = sum of strength[0..i]
38    const prefixSum: number[] = new Array(n + 1).fill(0);
39    for (let i = 0; i < n; i++) {
40        prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
41    }
42  
43    // Build prefix sum of prefix sums: prefixSumOfSums[i+1] = sum of prefixSum[0..i]
44    const prefixSumOfSums: number[] = new Array(n + 2).fill(0);
45    for (let i = 0; i <= n; i++) {
46        prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
47    }
48  
49    // Calculate the total strength
50    let totalResult = 0;
51  
52    for (let i = 0; i < n; i++) {
53        const minValue = strength[i];
54        const leftIdx = leftBound[i] + 1;   // Left boundary of subarrays where strength[i] is minimum
55        const rightIdx = rightBound[i] - 1;  // Right boundary of subarrays where strength[i] is minimum
56      
57        // Calculate contribution of all subarrays where strength[i] is the minimum
58        // leftContribution: sum of all subarrays ending at or after position i
59        const leftContribution = (i - leftIdx + 1) * (prefixSumOfSums[rightIdx + 2] - prefixSumOfSums[i + 1]);
60      
61        // rightContribution: sum of all subarrays ending before position i
62        const rightContribution = (rightIdx - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIdx]);
63      
64        // Add the contribution of strength[i] as minimum element
65        // Use modulo arithmetic to handle large numbers
66        const contribution = ((leftContribution - rightContribution) % MOD) * minValue;
67        totalResult = (totalResult + contribution % MOD) % MOD;
68    }
69  
70    // Handle negative modulo result by adding MOD if necessary
71    return (totalResult % MOD + MOD) % MOD;
72}
73

Time and Space Complexity

Time Complexity: O(n)

The algorithm consists of several linear passes through the array:

  • First monotonic stack traversal to compute left array: O(n) - each element is pushed and popped at most once
  • Second monotonic stack traversal to compute right array: O(n) - each element is pushed and popped at most once
  • Computing prefix sum array using accumulate twice: O(n) for each accumulate operation
  • Final loop to calculate the answer: O(n) - iterates through each element once with O(1) operations per iteration

Total time complexity: O(n) + O(n) + O(n) + O(n) + O(n) = O(n)

Space Complexity: O(n)

The algorithm uses the following additional space:

  • left array: O(n)
  • right array: O(n)
  • stk (reused twice): O(n) in worst case when all elements are in increasing/decreasing order
  • ss array (double prefix sum): O(n+1) = O(n)

Total space complexity: O(n)

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Incorrect Handling of Equal Elements in Monotonic Stack

One of the most critical pitfalls in this problem is incorrectly handling equal elements when finding the boundaries where each element serves as the minimum.

The Pitfall: If you use the same comparison operator (either >= or >) for both left and right boundary calculations, you'll count some subarrays multiple times when there are duplicate values.

For example, with strength = [2, 2, 2]:

  • If you use >= for both directions, all three elements would claim to be the minimum for the entire array
  • The subarray [2, 2, 2] would be counted three times instead of once

The Solution: Use asymmetric comparisons:

  • For left boundaries: Pop elements that are >= current (greater than or equal)
  • For right boundaries: Pop elements that are > current (strictly greater)

This ensures that when there are equal elements, only the leftmost one is chosen as the minimum for subarrays containing multiple equal values.

# Correct approach:
# Left boundary - use >=
while stack and strength[stack[-1]] >= current_strength:
    stack.pop()

# Right boundary - use > (strictly greater)
while stack and strength[stack[-1]] > strength[i]:
    stack.pop()

2. Integer Overflow with Large Numbers

The Pitfall: The multiplication and addition operations can produce very large numbers before taking the modulo, potentially causing integer overflow in languages with fixed integer sizes.

The Solution: In Python, this isn't an issue due to arbitrary precision integers, but it's good practice to apply modulo operations frequently:

# Instead of calculating everything then taking modulo once:
# total = (a - b) * v
# ans = (ans + total) % MOD

# Apply modulo at intermediate steps:
contribution = ((positive_contribution - negative_contribution) % MOD * min_strength) % MOD
total_strength_sum = (total_strength_sum + contribution) % MOD

3. Off-by-One Errors in Prefix Sum Calculations

The Pitfall: The double prefix sum array indexing can be confusing. It's easy to use wrong indices when calculating the sum contributions, especially with the +1 and +2 offsets.

The Solution: Remember that prefix_sum_of_prefix_sums has two extra levels of padding:

  • First accumulate adds one element at the beginning (initial=0)
  • Second accumulate adds another element at the beginning

So prefix_sum_of_prefix_sums[i+2] corresponds to the sum of prefix sums up to and including index i in the original array.

Always verify your indexing with small examples:

# For strength = [1, 2, 3]
# After first accumulate: [0, 1, 3, 6]
# After second accumulate: [0, 0, 1, 4, 10]
# prefix_sum_of_prefix_sums[i+2] gives sum of prefix sums up to index i

4. Misunderstanding the Contribution Formula

The Pitfall: The formula (a - b) * v for calculating each element's contribution is not intuitive and can be easily misimplemented.

The Solution: Break down what each part represents:

  • a = (ss[r + 2] - ss[i + 1]) * (i - l + 1): Sum of all subarrays that END at positions from i to r, multiplied by the number of possible starting positions
  • b = (ss[i + 1] - ss[l]) * (r - i + 1): Sum of all subarrays that START at positions from l to i, multiplied by the number of possible ending positions
  • The difference (a - b) gives the total sum of all subarrays where element i is the minimum

Test your understanding with a simple example before implementing.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Problem: Given a list of tasks and a list of requirements, compute a sequence of tasks that can be performed, such that we complete every task once while satisfying all the requirements.

Which of the following method should we use to solve this problem?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More