As the ruler of a kingdom, you have an army of wizards at your command.
You are given a 0-indexed integer array strength, where strength[i] denotes the strength of the ith wizard. For a contiguous group of wizards (i.e. the wizards' strengths form a subarray of strength), the total strength is defined as the product of the following two values:
Return the sum of the total strengths of all contiguous groups of wizards. Since the answer may be very large, return it modulo 109 + 7.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: strength = [1,3,1,2] Output: 44 Explanation: The following are all the contiguous groups of wizards: - [1] from [1,3,1,2] has a total strength of min([1]) * sum([1]) = 1 * 1 = 1 - [3] from [1,3,1,2] has a total strength of min([3]) * sum([3]) = 3 * 3 = 9 - [1] from [1,3,1,2] has a total strength of min([1]) * sum([1]) = 1 * 1 = 1 - [2] from [1,3,1,2] has a total strength of min([2]) * sum([2]) = 2 * 2 = 4 - [1,3] from [1,3,1,2] has a total strength of min([1,3]) * sum([1,3]) = 1 * 4 = 4 - [3,1] from [1,3,1,2] has a total strength of min([3,1]) * sum([3,1]) = 1 * 4 = 4 - [1,2] from [1,3,1,2] has a total strength of min([1,2]) * sum([1,2]) = 1 * 3 = 3 - [1,3,1] from [1,3,1,2] has a total strength of min([1,3,1]) * sum([1,3,1]) = 1 * 5 = 5 - [3,1,2] from [1,3,1,2] has a total strength of min([3,1,2]) * sum([3,1,2]) = 1 * 6 = 6 - [1,3,1,2] from [1,3,1,2] has a total strength of min([1,3,1,2]) * sum([1,3,1,2]) = 1 * 7 = 7 The sum of all the total strengths is 1 + 9 + 1 + 4 + 4 + 4 + 3 + 5 + 6 + 7 = 44.
Example 2:
Input: strength = [5,4,6] Output: 213 Explanation: The following are all the contiguous groups of wizards: - [5] from [5,4,6] has a total strength of min([5]) * sum([5]) = 5 * 5 = 25 - [4] from [5,4,6] has a total strength of min([4]) * sum([4]) = 4 * 4 = 16 - [6] from [5,4,6] has a total strength of min([6]) * sum([6]) = 6 * 6 = 36 - [5,4] from [5,4,6] has a total strength of min([5,4]) * sum([5,4]) = 4 * 9 = 36 - [4,6] from [5,4,6] has a total strength of min([4,6]) * sum([4,6]) = 4 * 10 = 40 - [5,4,6] from [5,4,6] has a total strength of min([5,4,6]) * sum([5,4,6]) = 4 * 15 = 60 The sum of all the total strengths is 25 + 16 + 36 + 36 + 40 + 60 = 213.
Constraints:
1 <= strength.length <= 1051 <= strength[i] <= 109When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach involves checking every single possible group of wizards and calculating their combined strength. We will consider every possible start and end point for these groups to find the total strength efficiently.
Here's how the algorithm would work step-by-step:
def sum_of_total_strength_brute_force(strengths):
total_strength = 0
number_of_wizards = len(strengths)
for start_index in range(number_of_wizards):
for end_index in range(start_index, number_of_wizards):
# Iterate through all possible sub-arrays (groups of wizards).
sub_array = strengths[start_index : end_index + 1]
minimum_strength = min(sub_array)
sum_of_strengths = sum(sub_array)
group_strength = minimum_strength * sum_of_strengths
total_strength += group_strength
# Mod operation to keep values within bounds to avoid overflow.
return total_strength % (10**9 + 7)The key idea is to efficiently compute the strength of all possible subarrays. To avoid redundant calculations, we use prefix sums and a clever trick with a 'next smaller element' approach to identify the minimum strength within each subarray in an efficient way.
Here's how the algorithm would work step-by-step:
def sum_of_total_strength(strengths): modulo = 10**9 + 7
array_length = len(strengths)
prefix_sums = [0] * (array_length + 1)
for i in range(array_length):
prefix_sums[i + 1] = (prefix_sums[i] + strengths[i]) % modulo
left_smaller = [0] * array_length
stack = []
for i in range(array_length):
while stack and strengths[stack[-1]] > strengths[i]:
stack.pop()
left_smaller[i] = stack[-1] if stack else -1
stack.append(i)
right_smaller = [0] * array_length
stack = []
for i in range(array_length - 1, -1, -1):
while stack and strengths[stack[-1]] >= strengths[i]:
stack.pop()
right_smaller[i] = stack[-1] if stack else array_length
stack.append(i)
total_strength_sum = 0
for i in range(array_length):
left_length = i - left_smaller[i]
right_length = right_smaller[i] - i
# Calculate the sum of all subarrays where strengths[i] is the minimum.
sum_left = (i - left_smaller[i]) % modulo
sum_right = (right_smaller[i] - i) % modulo
left_prefix_sum = (prefix_sums[i] - prefix_sums[max(i - left_length, 0)]) % modulo
right_prefix_sum = (prefix_sums[min(i + right_length, array_length)] - prefix_sums[i]) % modulo
# Apply modular arithmetic to avoid potential overflow
total_strength = (left_length * right_length) % modulo
total_strength = (total_strength * strengths[i]) % modulo
left_sum = (left_length * (left_length + 1) // 2) % modulo
right_sum = (right_length * (right_length + 1) // 2) % modulo
total_subarray_strength = (sum_left * sum_right) % modulo
# Computing the prefix sum is key to efficient subarray sums
total_subarray_strength = (total_subarray_strength * strengths[i]) % modulo
total_strength_sum = (total_strength_sum +
total_strength * (
((right_smaller[i] - i) * prefix_sums[i] % modulo -
(prefix_sums[max(0, i - left_length)] * (i - left_smaller[i]) % modulo )) % modulo
- (prefix_sums[i]- prefix_sums[i + 1] if i < array_length - 1 else prefix_sums[i] - prefix_sums[i]) % modulo
)) % modulo
total_strength_sum = (total_strength_sum + modulo) % modulo
return total_strength_sum| Case | How to Handle |
|---|---|
| Null or empty input array | Return 0 immediately as there are no wizards to calculate strength for. |
| Array with a single wizard | Return the strength of that single wizard raised to the power of 2, modulo the large prime. |
| Array with all wizards having the same strength | The prefix sum and sliding window should handle this correctly, but check for potential overflow issues during intermediate calculations. |
| Array with very large strengths, close to the modulo value | Ensure intermediate results are taken modulo the large prime to prevent overflow. |
| Array with strengths including 0 | The minimum value calculation must handle zero values without causing division by zero errors or incorrect strength calculations. |
| Input array with a large number of wizards (maximum constraints) | Ensure the prefix sum calculation and sliding window operations scale efficiently to avoid exceeding time limits (O(n) complexity). |
| Integer overflow during prefix sum calculation | Use long long data type for prefix sums to prevent integer overflow during intermediate calculations. |
| Array with negative wizard strengths | Problem description doesn't explicitly prohibit negative strength, so ensure the minimum value calculation can handle negative numbers correctly when computing the strength of each contiguous sub-array. |