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 }
复制代码

类似Next Greater Element I.

posted @   Dylan_Java_NYC  阅读(435)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示