LeetCode 2281. Sum of Total Strength of Wizards
原题链接在这里:https://leetcode.com/problems/sum-of-total-strength-of-wizards/
题目:
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:
- The strength of the weakest wizard in the group.
- The total of all the individual strengths of the wizards in the group.
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 <= 105
1 <= strength[i] <= 109
题解:
The idea is to use the strength[i] as the minimum number and find all the subarrays with strength[i] as minimum.
Then accumlate strength[i] * sum(subarrays).
Get minimum of subarray, use monotonic stack.
Get sum of subarray, use prefix sum.
left is array is to record first left smaller index where strength[left] < strength[i].
right is the array to record first right side smaller index where strength[i] >= strength[right].
The reason why we use < on left, but >= on right is to avoid duplicates. e.g. 2342, we want to use the second 2 when calcualte the strength.
To get the sum(subarrays),
For prefix starting with left + 1
sum(left + 1, ... i) = prefix[i + 1] - prefix[left + 1]
sum(left + 1, .... i + 1) = prefix[i + 2] - prefix[left + 1]
...
sum(left + 1, ... right - 1) = prefix[right] - prefix[left + 1].
For prefix starting with left + 2
sum(left + 2, ... i) = prefix[i + 1] - prefix[left + 2]
...
sum(left +2, ... right - 1) = prefix[right] - prefix[left + 2].
For prefix starting with i,
sum(i, .... i) = prefix[i + 1] - prefix[i].
...
sum(i, ... right - 1) = prefix[right] - prefix[i].
positive parts are (prefix[i + 1] + prefix[i + 2] +... + prefix[right]) * (i - left).
negative parts. are (prefix[left + 1] + prefrix[left + 2] + ... + prefix[i]) * (right - i).
All of these subarrays are having smallest as strength[i]. Accumlate strength[i] * total.
Time Complexity: O(n). n = strength.length.
Space: O(n).
AC Java:
1 class Solution { 2 public int totalStrength(int[] strength) { 3 int mod = 1000000007; 4 int n = strength.length; 5 int [] left = new int[n]; 6 int [] right = new int[n]; 7 Arrays.fill(right, n); 8 Stack<Integer> stk = new Stack<>(); 9 for(int i = 0; i < n; i++){ 10 while(!stk.isEmpty() && strength[stk.peek()] >= strength[i]){ 11 right[stk.pop()] = i; 12 } 13 14 left[i] = stk.isEmpty() ? -1 : stk.peek(); 15 stk.push(i); 16 } 17 18 long ac = 0; 19 long [] acc = new long[n + 2]; 20 for(int i = 1; i <= n; i++){ 21 ac += strength[i - 1]; 22 acc[i + 1] = (acc[i] + ac) % mod; 23 } 24 25 long res = 0; 26 for(int i = 0; i < n; i++){ 27 long total = ((long)(i - left[i]) * (acc[right[i] + 1] - acc[i + 1]) % mod + 2 * mod - (long)(right[i] - i) * (acc[i + 1] - acc[left[i] + 1]) % mod) % mod; 28 res = (res + total * strength[i]) % mod; 29 } 30 31 return (int)res; 32 } 33 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步