Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 094deed

Browse files
Merge pull request #747 from SharingSource/ac_oier
✨feat: add 891
2 parents 1fe9095 + a17d5ee commit 094deed

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

‎Index/数学.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
| [829. 连续整数求和](https://leetcode.cn/problems/consecutive-numbers-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/consecutive-numbers-sum/solution/by-ac_oier-220q/) | 困难 | 🤩🤩🤩🤩 |
5757
| [869. 重新排序得到 2 的幂](https://leetcode-cn.com/problems/reordered-power-of-2/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reordered-power-of-2/solution/gong-shui-san-xie-yi-ti-shuang-jie-dfs-c-3s1e/) | 中等 | 🤩🤩🤩🤩 |
5858
| [879. 盈利计划](https://leetcode-cn.com/problems/profitable-schemes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/profitable-schemes/solution/gong-shui-san-xie-te-shu-duo-wei-fei-yon-7su9/) | 困难 | 🤩🤩🤩🤩🤩 |
59+
| [891. 子序列宽度之和](https://leetcode.cn/problems/sum-of-subsequence-widths/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subsequence-widths/solution/by-ac_oier-6tyk/) | 困难 | 🤩🤩🤩🤩 |
5960
| [907. 子数组的最小值之和](https://leetcode.cn/problems/sum-of-subarray-minimums/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subarray-minimums/solution/by-ac_oier-h9cd/) | 中等 | 🤩🤩🤩 |
6061
| [952. 按公因数计算最大组件大小](https://leetcode.cn/problems/largest-component-size-by-common-factor/) | [LeetCode 题解链接](https://leetcode.cn/problems/largest-component-size-by-common-factor/solution/by-ac_oier-mw04/) | 困难 | 🤩🤩🤩🤩🤩 |
6162
| [1006. 笨阶乘](https://leetcode-cn.com/problems/clumsy-factorial/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/clumsy-factorial/solution/gong-shui-san-xie-tong-yong-biao-da-shi-nngfp/) | 中等 | 🤩🤩🤩 |
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[891. 子序列宽度之和](https://leetcode.cn/problems/sum-of-subsequence-widths/solution/by-ac_oier-6tyk/)** ,难度为 **困难**
4+
5+
Tag : 「数学」
6+
7+
8+
9+
一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。
10+
11+
给你一个整数数组 `nums`,返回 `nums` 的所有非空 子序列 的 宽度之和 。由于答案可能非常大,请返回对 10ドル^9 + 7$ 取余 后的结果。
12+
13+
子序列 定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数组。例如,`[3,6,2,7]` 就是数组 `[0,3,1,6,2,2,7]` 的一个子序列。
14+
15+
示例 1:
16+
```
17+
输入:nums = [2,1,3]
18+
19+
输出:6
20+
21+
解释:子序列为 [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3] 。
22+
相应的宽度是 0, 0, 0, 1, 1, 2, 2 。
23+
宽度之和是 6 。
24+
```
25+
示例 2:
26+
```
27+
输入:nums = [2]
28+
29+
输出:0
30+
```
31+
32+
提示:
33+
* 1ドル <= nums.length <= 10^5$
34+
* 1ドル <= nums[i] <= 10^5$
35+
36+
---
37+
38+
### 数学
39+
40+
#### 提示一:每个子序列对答案的贡献
41+
42+
对于某个子序列而言,若其最大值为 $a,ドル最小值为 $b,ドル则该子序列对答案的贡献为 $(a - b)$。
43+
44+
我们有若干个子序列,即有若干个 $(a - b),ドル答案为所有 $(a - b)$ 之和,我们称一个 $(a - b)$ 为 `item`
45+
46+
#### 提示二:每个 $nums[i]$ 参与了多少个 `item` 的组成,在最终展开式中又是如何
47+
48+
对于每个 $(a - b)$ 而言,`a``b` 均必然是具体的 $nums[i]$。
49+
50+
同时易知若 $nums[i]$ 作为了 $k$ 个子序列的最小值,那么在最终表达式展开中,必然有 $k$ 个 $-nums[i]$;同理若 $nums[i]$ 作为了 $k$ 个子序列的最大值,那么在最终表达式展开中,必然有 $k$ 个 $nums[i]$。
51+
52+
#### 提示三:统计每个 $nums[i]$ 作为最值时,有多少个子序列
53+
54+
先不考虑 $nums[i]$ 的重复问题。
55+
56+
若 $nums[i]$ 作为子序列最小值时,首先 $nums[i]$ 必选,小于 $nums[i]$ 的必不选,而大于 $nums[i]$ 的可选可不选,组合个数取决于大于 $nums[i]$ 的数的个数,假设有 $k$ 个,那么根据组合数原理,共有 2ドル^k$ 个组合,即共有 2ドル^k$ 个子序列。此时 $nums[i]$ 对答案的贡献为 2ドル^k \times (-nums[i])$。
57+
58+
同理,$nums[i]$ 作为子序列最大值时,子序列个数取决于小于 $nums[i]$ 的数的个数,假设有 $k$ 个,此时 $nums[i]$ 对答案的贡献为 2ドル^k \times nums[i]$。
59+
60+
#### 提示四:如何快速得知比 $nums[i]$ 大/小 的数的个数
61+
62+
排序。
63+
64+
#### 提示五:$nums[i]$ 的重复问题
65+
66+
无论是将 $nums[i]$ 视作最大值还是最小值,我们的组合数均取决于某一侧的数的个数,因此不会答案正确性产生影响。
67+
68+
#### 提示六:2ドル^k$ 操作的重复计算问题
69+
70+
将 $nums[i]$ 视作最值,我们都需要统计两边数所产生的组合数个数,因此即使对于单个用例都会面临重复计算某个 2ドル^k$ 的问题(对称性)。
71+
72+
同时对于跨样例而言,我们仍会重复计算某些 2ドル^k$(尤其是较小的 $k$ 值),为避免重复计算,我们可以通过打表预处理的方式算得所有可能要用到 2ドル^k$ 结果,在使用的时候直接通过查表取得。
73+
74+
Java 代码:
75+
```Java
76+
class Solution {
77+
static int N = 100010, MOD = (int)1e9+7;
78+
static long[] p = new long[N];
79+
static {
80+
p[0] = 1;
81+
for (int i = 1; i < N; i++) p[i] = p[i - 1] * 2 % MOD;
82+
}
83+
public int sumSubseqWidths(int[] nums) {
84+
int n = nums.length;
85+
long ans = 0;
86+
Arrays.sort(nums);
87+
for (int i = 0; i < n; i++) {
88+
ans += (p[i] * nums[i]) % MOD;
89+
ans %= MOD;
90+
ans -= (p[n - i - 1] * nums[i]) % MOD;
91+
ans %= MOD;
92+
}
93+
return (int) ans;
94+
}
95+
}
96+
```
97+
TypeScript 代码:
98+
```TypeScript
99+
function sumSubseqWidths(nums: number[]): number {
100+
let n = nums.length, mod = 1000000007, ans = 0
101+
const p = new Array<number>(n + 10).fill(1)
102+
for (let i = 1; i <= n; i++) p[i] = p[i - 1] * 2 % mod
103+
nums.sort((a,b)=>a-b)
104+
for (let i = 0; i < n; i++) {
105+
ans += p[i] * nums[i] % mod
106+
ans %= mod
107+
ans -= p[n - i - 1] * nums[i] % mod
108+
ans %= mod
109+
}
110+
return ans
111+
}
112+
```
113+
Python3 代码:
114+
```Python3
115+
class Solution:
116+
def sumSubseqWidths(self, nums: List[int]) -> int:
117+
n, mod, ans = len(nums), 1000000007, 0
118+
p = [1] * (n + 10)
119+
for i in range(1, n + 1):
120+
p[i] = p[i - 1] * 2 % mod
121+
nums.sort()
122+
for i in range(n):
123+
ans = ans + p[i] * nums[i] % mod
124+
ans = ans - p[n - i - 1] * nums[i] % mod
125+
return ans % mod
126+
```
127+
* 时间复杂度:排序复杂度为 $O(n\log{n})$;统计答案复杂度为 $O(n)$。整体复杂度为 $O(n\log{n})$
128+
* 空间复杂度:$O(n)$
129+
130+
---
131+
132+
### 最后
133+
134+
这是我们「刷穿 LeetCode」系列文章的第 `No.891` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
135+
136+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
137+
138+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
139+
140+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
141+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /