原文链接: https://leetcode-cn.com/problems/sum-of-subsequence-widths
英文原文
The width of a sequence is the difference between the maximum and minimum elements in the sequence.
Given an array of integers nums
, return the sum of the widths of all the non-empty subsequences of nums
. Since the answer may be very large, return it modulo 109 + 7
.
A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7]
is a subsequence of the array [0,3,1,6,2,2,7]
.
Example 1:
Input: nums = [2,1,3] Output: 6 Explanation: The 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.
Example 2:
Input: nums = [2] Output: 0
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
中文题目
给定一个整数数组 A
,考虑 A
的所有非空子序列。
对于任意序列 S ,设 S 的宽度是 S 的最大元素和最小元素的差。
返回 A 的所有子序列的宽度之和。
由于答案可能非常大,请返回答案模 10^9+7。
示例:
输入:[2,1,3] 输出:6 解释: 子序列为 [1],[2],[3],[2,1],[2,3],[1,3],[2,1,3] 。 相应的宽度是 0,0,0,1,1,2,2 。 这些宽度之和是 6 。
提示:
1 <= A.length <= 20000
1 <= A[i] <= 20000
通过代码
官方题解
方法:数学
思路
让我们试着统计具有最小值 A[i]
和最大值 A[j]
的子序列的数量。
算法
我们可以对数组进行排序,因为这并不会改变答案。对数组进行排序后,我们可以得知有最小值 A[i]
和最大值 A[j]
的子序列的数目是 $2^{j-i-1}$。因此,期望的答案为:
$$
\sum\limits_{j > i} (2^{j-i-1}) (A_j - A_i)
$$
$$
= \big( \sum\limits_{i = 0}^{n-2} \sum\limits_{j = i+1}^{n-1} (2^{j-i-1}) (A_j) \big) - \big( \sum\limits_{i = 0}^{n-2} \sum\limits_{j = i+1}^{n-1} (2^{j-i-1}) (A_i) \big)
$$
$$
= \big( (2^0 A_1 + 2^1 A_2 + 2^2 A_3 + \cdots) + (2^0 A_2 + 2^1 A_3 + \cdots) + (2^0 A_3 + 2^1 A_4 + \cdots) + \cdots \big)
$$
$$
- \big( \sum\limits_{i = 0}^{n-2} (2^0 + 2^1 + \cdots + 2^{N-i-2}) (A_i) \big)
$$
$$
= \big( \sum\limits_{j = 1}^{n-1} (2^j - 1) A_j \big) - \big( \sum\limits_{i = 0}^{n-2} (2^{N-i-1} - 1) A_i \big)
$$
$$
= \sum\limits_{i = 0}^{n-1} \big(((2^i - 1) A_i) - ((2^{N-i-1} - 1) A_i)\big)
$$
$$
= \sum\limits_{i = 0}^{n-1} (2^i - 2^{N-i-1}) A_i
$$
class Solution {
public int sumSubseqWidths(int[] A) {
int MOD = 1_000_000_007;
int N = A.length;
Arrays.sort(A);
long[] pow2 = new long[N];
pow2[0] = 1;
for (int i = 1; i < N; ++i)
pow2[i] = pow2[i-1] * 2 % MOD;
long ans = 0;
for (int i = 0; i < N; ++i)
ans = (ans + (pow2[i] - pow2[N-1-i]) * A[i]) % MOD;
return (int) ans;
}
}
class Solution(object):
def sumSubseqWidths(self, A):
MOD = 10**9 + 7
N = len(A)
A.sort()
pow2 = [1]
for i in xrange(1, N):
pow2.append(pow2[-1] * 2 % MOD)
ans = 0
for i, x in enumerate(A):
ans = (ans + (pow2[i] - pow2[N-1-i]) * x) % MOD
return ans
复杂度分析
时间复杂度:$O(N \log N)$,其中 $N$ 是
A
的长度。空间复杂度:$O(N)$,
pow2
所用的空间。(我们可以通过动态地计算这些乘方将其改进到 $O(1)$)。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
2934 | 8890 | 33.0% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|