Skip to content

Commit 2c67256

Browse files
committed
feat: add solutions to lc problem: No.0891
No.0891.Sum of Subsequence Widths
1 parent 4bc5015 commit 2c67256

File tree

7 files changed

+200
-12
lines changed

7 files changed

+200
-12
lines changed

solution/0700-0799/0795.Number of Subarrays with Bounded Maximum/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
**方法一:单调栈**
4545

46-
我们可以枚举数组中每个元素作为子数组的最大值,然后统计以该元素为最大值的子数组的个数。问题转化为求出每个元素 $nums[i]$ 左侧第一个大于该元素的下标 $l[i]$,右侧第一个大于等于该元素的下标 $r[i]$,则以该元素为最大值的子数组的个数为 $(i - left[i]) \times (right[i] - i)$。
46+
我们可以枚举数组中每个元素作为子数组的最大值,然后统计以该元素为最大值的子数组的个数。问题转化为求出每个元素 $nums[i]$ 左侧第一个大于该元素的下标 $l[i]$,右侧第一个大于等于该元素的下标 $r[i]$,则以该元素为最大值的子数组的个数为 $(i - l[i]) \times (r[i] - i)$。
4747

4848
我们可以使用单调栈求出 $l[i]$ 和 $r[i]$。
4949

solution/0800-0899/0891.Sum of Subsequence Widths/README.md

+99-1
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,120 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47+
**方法一:排序 + 枚举贡献**
48+
49+
题目求解的是数组 `nums` 中所有子序列中最大值与最小值差值之和,注意到“子序列”,并且涉及到“最大值”与“最小值”,我们考虑先对数组 `nums` 进行排序。
50+
51+
然后我们枚举数组 `nums` 中的每个元素 $nums[i]$,该元素左侧的元素个数为 $i$,右侧的元素个数为 $n-i-1$。
52+
53+
如果我们将元素 $nums[i]$ 作为子序列的最大值,总共有多少个满足条件的子序列呢?显然,子序列的其他元素应该从左侧的 $i$ 个元素中选取,每个元素有两种选择,即选或不选,因此总共有 $2^i$ 个子序列。同理,如果我们将元素 $nums[i]$ 作为子序列的最小值,那么总共有 $2^{n-i-1}$ 个满足条件的子序列。因此 $nums[i]$ 对答案的贡献为:
54+
55+
$$
56+
\begin{aligned}
57+
nums[i] \times (2^i - 2^{n-i-1})
58+
\end{aligned}
59+
$$
60+
61+
我们将数组 `nums` 中所有元素的贡献累加,即为答案:
62+
63+
$$
64+
\begin{aligned}
65+
\sum_{i=0}^{n-1} nums[i] \times (2^i - 2^{n-i-1})
66+
\end{aligned}
67+
$$
68+
69+
我们将上述式子展开,可以得到:
70+
71+
$$
72+
\begin{aligned}
73+
nums[0] \times (2^0 - 2^{n-1}) + nums[1] \times (2^1 - 2^{n-2}) + ... + nums[n-1] \times (2^{n-1} - 2^0)
74+
\end{aligned}
75+
$$
76+
77+
再将式子中相同的幂次项合并,可以得到:
78+
79+
$$
80+
\begin{aligned}
81+
(nums[0] - nums[n-1]) \times 2^0 + (nums[1] - nums[n-2]) \times 2^1 + ... + (nums[n-1] - nums[0]) \times 2^{n-1}
82+
\end{aligned}
83+
$$
84+
85+
因此我们只需要对数组 `nums` 进行排序,然后计算上述的贡献即可。注意答案的取模操作。
86+
87+
时间复杂度 $O(n\times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组 `nums` 的长度。
88+
4789
<!-- tabs:start -->
4890

4991
### **Python3**
5092

5193
<!-- 这里可写当前语言的特殊实现逻辑 -->
5294

5395
```python
54-
96+
class Solution:
97+
def sumSubseqWidths(self, nums: List[int]) -> int:
98+
mod = 10**9 + 7
99+
nums.sort()
100+
ans, p = 0, 1
101+
for i, v in enumerate(nums):
102+
ans = (ans + (v - nums[-i - 1]) * p) % mod
103+
p = (p << 1) % mod
104+
return ans
55105
```
56106

57107
### **Java**
58108

59109
<!-- 这里可写当前语言的特殊实现逻辑 -->
60110

61111
```java
112+
class Solution {
113+
private static final int MOD = (int) 1e9 + 7;
114+
115+
public int sumSubseqWidths(int[] nums) {
116+
Arrays.sort(nums);
117+
long ans = 0, p = 1;
118+
int n = nums.length;
119+
for (int i = 0; i < n; ++i) {
120+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + MOD) % MOD;
121+
p = (p << 1) % MOD;
122+
}
123+
return (int) ans;
124+
}
125+
}
126+
```
127+
128+
### **C++**
129+
130+
```cpp
131+
class Solution {
132+
public:
133+
const int mod = 1e9 + 7;
134+
135+
int sumSubseqWidths(vector<int>& nums) {
136+
sort(nums.begin(), nums.end());
137+
long ans = 0, p = 1;
138+
int n = nums.size();
139+
for (int i = 0; i < n; ++i) {
140+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + mod) % mod;
141+
p = (p << 1) % mod;
142+
}
143+
return ans;
144+
}
145+
};
146+
```
62147

148+
### **Go**
149+
150+
```go
151+
func sumSubseqWidths(nums []int) (ans int) {
152+
const mod int = 1e9 + 7
153+
sort.Ints(nums)
154+
p, n := 1, len(nums)
155+
for i, v := range nums {
156+
ans = (ans + (v-nums[n-i-1])*p + mod) % mod
157+
p = (p << 1) % mod
158+
}
159+
return
160+
}
63161
```
64162

65163
### **...**

solution/0800-0899/0891.Sum of Subsequence Widths/README_EN.md

+57-1
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,69 @@ The sum of these widths is 6.
4343
### **Python3**
4444

4545
```python
46-
46+
class Solution:
47+
def sumSubseqWidths(self, nums: List[int]) -> int:
48+
mod = 10**9 + 7
49+
nums.sort()
50+
ans, p = 0, 1
51+
for i, v in enumerate(nums):
52+
ans = (ans + (v - nums[-i - 1]) * p) % mod
53+
p = (p << 1) % mod
54+
return ans
4755
```
4856

4957
### **Java**
5058

5159
```java
60+
class Solution {
61+
private static final int MOD = (int) 1e9 + 7;
62+
63+
public int sumSubseqWidths(int[] nums) {
64+
Arrays.sort(nums);
65+
long ans = 0, p = 1;
66+
int n = nums.length;
67+
for (int i = 0; i < n; ++i) {
68+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + MOD) % MOD;
69+
p = (p << 1) % MOD;
70+
}
71+
return (int) ans;
72+
}
73+
}
74+
```
75+
76+
### **C++**
77+
78+
```cpp
79+
class Solution {
80+
public:
81+
const int mod = 1e9 + 7;
82+
83+
int sumSubseqWidths(vector<int>& nums) {
84+
sort(nums.begin(), nums.end());
85+
long ans = 0, p = 1;
86+
int n = nums.size();
87+
for (int i = 0; i < n; ++i) {
88+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + mod) % mod;
89+
p = (p << 1) % mod;
90+
}
91+
return ans;
92+
}
93+
};
94+
```
5295

96+
### **Go**
97+
98+
```go
99+
func sumSubseqWidths(nums []int) (ans int) {
100+
const mod int = 1e9 + 7
101+
sort.Ints(nums)
102+
p, n := 1, len(nums)
103+
for i, v := range nums {
104+
ans = (ans + (v-nums[n-i-1])*p + mod) % mod
105+
p = (p << 1) % mod
106+
}
107+
return
108+
}
53109
```
54110

55111
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution {
2+
public:
3+
const int mod = 1e9 + 7;
4+
5+
int sumSubseqWidths(vector<int>& nums) {
6+
sort(nums.begin(), nums.end());
7+
long ans = 0, p = 1;
8+
int n = nums.size();
9+
for (int i = 0; i < n; ++i) {
10+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + mod) % mod;
11+
p = (p << 1) % mod;
12+
}
13+
return ans;
14+
}
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
func sumSubseqWidths(nums []int) (ans int) {
2+
const mod int = 1e9 + 7
3+
sort.Ints(nums)
4+
p, n := 1, len(nums)
5+
for i, v := range nums {
6+
ans = (ans + (v-nums[n-i-1])*p + mod) % mod
7+
p = (p << 1) % mod
8+
}
9+
return
10+
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
class Solution {
2-
public int sumSubseqWidths(int[] A) {
3-
final int MOD = (int) (1e9 + 7);
4-
Arrays.sort(A);
5-
int n = A.length;
6-
long res = 0;
7-
long p = 1;
2+
private static final int MOD = (int) 1e9 + 7;
3+
4+
public int sumSubseqWidths(int[] nums) {
5+
Arrays.sort(nums);
6+
long ans = 0, p = 1;
7+
int n = nums.length;
88
for (int i = 0; i < n; ++i) {
9-
res = (res + (A[i] - A[n - 1 - i]) * p) % MOD;
9+
ans = (ans + (nums[i] - nums[n - i - 1]) * p + MOD) % MOD;
1010
p = (p << 1) % MOD;
1111
}
12-
return (int) ((res + MOD) % MOD);
12+
return (int) ans;
1313
}
14-
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution:
2+
def sumSubseqWidths(self, nums: List[int]) -> int:
3+
mod = 10**9 + 7
4+
nums.sort()
5+
ans, p = 0, 1
6+
for i, v in enumerate(nums):
7+
ans = (ans + (v - nums[-i - 1]) * p) % mod
8+
p = (p << 1) % mod
9+
return ans

0 commit comments

Comments
 (0)