891. Sum of Subsequence Widths

时间:2020-05-16 16:23:50   收藏:0   阅读:52

问题:

给定数组,求所有子数组的最大值最小值之差的总和是多少。

这个数若太大了,对其进行取kMod=10^9+7的模

Example 1:
Input: [2,1,3]
Output: 6
Explanation:
Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].
The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
The sum of these widths is 6.
 

Note:
1 <= A.length <= 20000
1 <= A[i] <= 20000

  

解法:

求所有子数组的最大最小之之差 的和,即是:

所有子数组的最大值之和-最小值之和。

★先对A进行排序。

那么对于其中任意A[i]

1.若在某个子数组中,A[i]=最大值:那么该子数组的元素<=A[i]

 ★(因为已排序)这样的子数组共有,2^i 个。

那么对于A[i]作为最大值,对res的贡献即是+A[i],所以总贡献为:+ (A[i] * 2^i) 

2.若在某个子数组中,A[i]=最小值:那么该子数组的元素>=A[i]

 ★(因为已排序)这样的子数组共有,2^(n-i-1) 个。(n=A.size())
那么对于A[i]作为最小值,对res的贡献即是-A[i],所以总贡献为:- (A[i] * 2^(n-i-1))

3.因此对于每一个A[i],对res的贡献为:

(A[i] * 2^i) - (A[i] * 2^(n-i-1))

那么所有的元素的贡献和为:

res= Sum(A[i] * 2^i) - (A[i] * 2^(n-i-1)), 1<=i<n

为了简化每次单独计算 2^i 和 2^(n-i-1) 的重复性。我们可以展开上述式子,

合并同样为 2^i 的项。

做如下转换:

技术图片

 

 可得:

res = Sum(A[i] * 2^i - A[n-i-1] * 2^i)

= Sum((A[i] - A[n-i-1]) * 2^i) , 1<=i<n

另p=2^i

i=0时,p=1,

i=1时,p=p*2=p<<1

......

由于p可能会成为一个非常大的数,因此我们在循环计算途中,最好同时取模

(a+b)%kMod = (a%kMod + b%kMod) %kMod

(a*b)%kMod = (a%kMod * b%kMod) %kMod

所以:p=(p<<1)%kMod

 

参考代码:

 1 class Solution {
 2 public:
 3     int sumSubseqWidths(vector<int>& A) {
 4         long res=0, p=1;
 5         long kMod=1e9+7;//科学计数法 1e9=1*10^9  1.34e-5=1.34*10^(-5)
 6         sort(A.begin(), A.end());
 7         int n=A.size();
 8         for(int i=0; i<n; i++){
 9             res = (res + (A[i]-A[n-i-1])*p) % kMod;
10             p = (p<<1) % kMod;
11         }
12         return res;
13     }
14 };

 

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!