Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 10ce174

Browse files
authored
feat: add solutions to lc problem: No.3299 (doocs#3564)
No.3299.Sum of Consecutive Subsequences
1 parent f4e3924 commit 10ce174

File tree

6 files changed

+422
-10
lines changed

6 files changed

+422
-10
lines changed

solution/3200-3299/3299.Sum of Consecutive Subsequences/README.md

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,172 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3299.Su
7070

7171
<!-- solution:start -->
7272

73-
### 方法一
73+
### 方法一:枚举贡献
74+
75+
我们不妨统计每个元素 $\textit{nums}[i]$ 在多少个长度大于 $1$ 的连续子序列中出现,那么其个数乘以 $\textit{nums}[i]$ 就是 $\textit{nums}[i]$ 在所有长度大于 $1$ 的连续子序列中的贡献。我们将其累加,再加上所有元素的和,即为答案。
76+
77+
我们可以先统计连续递增子序列对答案的贡献,再统计连续递减子序列对答案的贡献,最后再加上所有元素的和即可。
78+
79+
在实现上,我们定义一个函数 $\textit{calc}(\textit{nums})$,其中 $\textit{nums}$ 是一个数组,返回 $\textit{nums}$ 所有长度大于 $1$ 的连续子序列的和。
80+
81+
在函数中,我们可以使用两个数组 $\textit{left}$ 和 $\textit{right}$ 分别记录每个元素 $\textit{nums}[i]$ 的左侧以 $\textit{nums}[i] - 1$ 结尾的连续递增子序列的个数,以及右侧以 $\textit{nums}[i] + 1$ 开头的连续递增子序列的个数。这样,我们就可以在 $O(n)$ 的时间复杂度内计算出 $\textit{nums}$ 在所有长度大于 $1$ 的连续子序列中的贡献。
82+
83+
在主函数中,我们首先调用 $\textit{calc}(\textit{nums})$ 计算出连续递增子序列对答案的贡献,然后将 $\textit{nums}$ 反转后再次调用 $\textit{calc}(\textit{nums})$ 计算出连续递减子序列对答案的贡献,最后再加上所有元素的和即为答案。
84+
85+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
7486

7587
<!-- tabs:start -->
7688

7789
#### Python3
7890

7991
```python
80-
92+
class Solution:
93+
def getSum(self, nums: List[int]) -> int:
94+
def calc(nums: List[int]) -> int:
95+
n = len(nums)
96+
left = [0] * n
97+
right = [0] * n
98+
cnt = Counter()
99+
for i in range(1, n):
100+
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1]
101+
left[i] = cnt[nums[i] - 1]
102+
cnt = Counter()
103+
for i in range(n - 2, -1, -1):
104+
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1]
105+
right[i] = cnt[nums[i] + 1]
106+
return sum((l + r + l * r) * x for l, r, x in zip(left, right, nums)) % mod
107+
108+
mod = 10**9 + 7
109+
x = calc(nums)
110+
nums.reverse()
111+
y = calc(nums)
112+
return (x + y + sum(nums)) % mod
81113
```
82114

83115
#### Java
84116

85117
```java
86-
118+
class Solution {
119+
private final int mod = (int) 1e9 + 7;
120+
121+
public int getSum(int[] nums) {
122+
long x = calc(nums);
123+
for (int i = 0, j = nums.length - 1; i < j; ++i, --j) {
124+
int t = nums[i];
125+
nums[i] = nums[j];
126+
nums[j] = t;
127+
}
128+
long y = calc(nums);
129+
long s = Arrays.stream(nums).asLongStream().sum();
130+
return (int) ((x + y + s) % mod);
131+
}
132+
133+
private long calc(int[] nums) {
134+
int n = nums.length;
135+
long[] left = new long[n];
136+
long[] right = new long[n];
137+
Map<Integer, Long> cnt = new HashMap<>();
138+
for (int i = 1; i < n; ++i) {
139+
cnt.merge(nums[i - 1], 1 + cnt.getOrDefault(nums[i - 1] - 1, 0L), Long::sum);
140+
left[i] = cnt.getOrDefault(nums[i] - 1, 0L);
141+
}
142+
cnt.clear();
143+
for (int i = n - 2; i >= 0; --i) {
144+
cnt.merge(nums[i + 1], 1 + cnt.getOrDefault(nums[i + 1] + 1, 0L), Long::sum);
145+
right[i] = cnt.getOrDefault(nums[i] + 1, 0L);
146+
}
147+
long ans = 0;
148+
for (int i = 0; i < n; ++i) {
149+
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
150+
}
151+
return ans;
152+
}
153+
}
87154
```
88155

89156
#### C++
90157

91158
```cpp
92-
159+
class Solution {
160+
public:
161+
int getSum(vector<int>& nums) {
162+
using ll = long long;
163+
const int mod = 1e9 + 7;
164+
auto calc = [&](const vector<int>& nums) -> ll {
165+
int n = nums.size();
166+
vector<ll> left(n), right(n);
167+
unordered_map<int, ll> cnt;
168+
169+
for (int i = 1; i < n; ++i) {
170+
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1];
171+
left[i] = cnt[nums[i] - 1];
172+
}
173+
174+
cnt.clear();
175+
176+
for (int i = n - 2; i >= 0; --i) {
177+
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1];
178+
right[i] = cnt[nums[i] + 1];
179+
}
180+
181+
ll ans = 0;
182+
for (int i = 0; i < n; ++i) {
183+
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
184+
}
185+
return ans;
186+
};
187+
188+
ll x = calc(nums);
189+
reverse(nums.begin(), nums.end());
190+
ll y = calc(nums);
191+
ll s = accumulate(nums.begin(), nums.end(), 0LL);
192+
return static_cast<int>((x + y + s) % mod);
193+
}
194+
};
93195
```
94196

95197
#### Go
96198

97199
```go
98-
200+
func getSum(nums []int) int {
201+
const mod = 1e9 + 7
202+
203+
calc := func(nums []int) int64 {
204+
n := len(nums)
205+
left := make([]int64, n)
206+
right := make([]int64, n)
207+
cnt := make(map[int]int64)
208+
209+
for i := 1; i < n; i++ {
210+
cnt[nums[i-1]] += 1 + cnt[nums[i-1]-1]
211+
left[i] = cnt[nums[i]-1]
212+
}
213+
214+
cnt = make(map[int]int64)
215+
216+
for i := n - 2; i >= 0; i-- {
217+
cnt[nums[i+1]] += 1 + cnt[nums[i+1]+1]
218+
right[i] = cnt[nums[i]+1]
219+
}
220+
221+
var ans int64
222+
for i, x := range nums {
223+
ans = (ans + (left[i]+right[i]+(left[i]*right[i]%mod))*int64(x)%mod) % mod
224+
}
225+
return ans
226+
}
227+
228+
x := calc(nums)
229+
for i, j := 0, len(nums)-1; i < j; i, j = i+1, j-1 {
230+
nums[i], nums[j] = nums[j], nums[i]
231+
}
232+
y := calc(nums)
233+
s := int64(0)
234+
for _, num := range nums {
235+
s += int64(num)
236+
}
237+
return int((x + y + s) % mod)
238+
}
99239
```
100240

101241
<!-- tabs:end -->

solution/3200-3299/3299.Sum of Consecutive Subsequences/README_EN.md

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,172 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3299.Su
7070

7171
<!-- solution:start -->
7272

73-
### Solution 1
73+
### Solution 1: Enumeration of Contributions
74+
75+
Let us count how many times each element $\textit{nums}[i]$ appears in a continuous subsequence of length greater than 1. Then, multiplying this count by $\textit{nums}[i]$ gives the contribution of $\textit{nums}[i]$ in all continuous subsequences of length greater than 1. We sum these contributions, and adding the sum of all elements, we get the answer.
76+
77+
We can first compute the contribution of strictly increasing subsequences, then the contribution of strictly decreasing subsequences, and finally add the sum of all elements.
78+
79+
To implement this, we define a function $\textit{calc}(\textit{nums})$, where $\textit{nums}$ is an array. This function returns the sum of all continuous subsequences of length greater than 1 in $\textit{nums}$.
80+
81+
In the function, we can use two arrays, $\textit{left}$ and $\textit{right}$, to record the number of strictly increasing subsequences ending with $\textit{nums}[i] - 1$ on the left of each element $\textit{nums}[i]$, and the number of strictly increasing subsequences starting with $\textit{nums}[i] + 1$ on the right of each element $\textit{nums}[i]$. In this way, we can calculate the contribution of $\textit{nums}$ in all continuous subsequences of length greater than 1 in $O(n)$ time complexity.
82+
83+
In the main function, we first call $\textit{calc}(\textit{nums})$ to compute the contribution of strictly increasing subsequences, then reverse $\textit{nums}$ and call $\textit{calc}(\textit{nums})$ again to compute the contribution of strictly decreasing subsequences. Finally, adding the sum of all elements gives the answer.
84+
85+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$.
7486

7587
<!-- tabs:start -->
7688

7789
#### Python3
7890

7991
```python
80-
92+
class Solution:
93+
def getSum(self, nums: List[int]) -> int:
94+
def calc(nums: List[int]) -> int:
95+
n = len(nums)
96+
left = [0] * n
97+
right = [0] * n
98+
cnt = Counter()
99+
for i in range(1, n):
100+
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1]
101+
left[i] = cnt[nums[i] - 1]
102+
cnt = Counter()
103+
for i in range(n - 2, -1, -1):
104+
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1]
105+
right[i] = cnt[nums[i] + 1]
106+
return sum((l + r + l * r) * x for l, r, x in zip(left, right, nums)) % mod
107+
108+
mod = 10**9 + 7
109+
x = calc(nums)
110+
nums.reverse()
111+
y = calc(nums)
112+
return (x + y + sum(nums)) % mod
81113
```
82114

83115
#### Java
84116

85117
```java
86-
118+
class Solution {
119+
private final int mod = (int) 1e9 + 7;
120+
121+
public int getSum(int[] nums) {
122+
long x = calc(nums);
123+
for (int i = 0, j = nums.length - 1; i < j; ++i, --j) {
124+
int t = nums[i];
125+
nums[i] = nums[j];
126+
nums[j] = t;
127+
}
128+
long y = calc(nums);
129+
long s = Arrays.stream(nums).asLongStream().sum();
130+
return (int) ((x + y + s) % mod);
131+
}
132+
133+
private long calc(int[] nums) {
134+
int n = nums.length;
135+
long[] left = new long[n];
136+
long[] right = new long[n];
137+
Map<Integer, Long> cnt = new HashMap<>();
138+
for (int i = 1; i < n; ++i) {
139+
cnt.merge(nums[i - 1], 1 + cnt.getOrDefault(nums[i - 1] - 1, 0L), Long::sum);
140+
left[i] = cnt.getOrDefault(nums[i] - 1, 0L);
141+
}
142+
cnt.clear();
143+
for (int i = n - 2; i >= 0; --i) {
144+
cnt.merge(nums[i + 1], 1 + cnt.getOrDefault(nums[i + 1] + 1, 0L), Long::sum);
145+
right[i] = cnt.getOrDefault(nums[i] + 1, 0L);
146+
}
147+
long ans = 0;
148+
for (int i = 0; i < n; ++i) {
149+
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
150+
}
151+
return ans;
152+
}
153+
}
87154
```
88155

89156
#### C++
90157

91158
```cpp
92-
159+
class Solution {
160+
public:
161+
int getSum(vector<int>& nums) {
162+
using ll = long long;
163+
const int mod = 1e9 + 7;
164+
auto calc = [&](const vector<int>& nums) -> ll {
165+
int n = nums.size();
166+
vector<ll> left(n), right(n);
167+
unordered_map<int, ll> cnt;
168+
169+
for (int i = 1; i < n; ++i) {
170+
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1];
171+
left[i] = cnt[nums[i] - 1];
172+
}
173+
174+
cnt.clear();
175+
176+
for (int i = n - 2; i >= 0; --i) {
177+
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1];
178+
right[i] = cnt[nums[i] + 1];
179+
}
180+
181+
ll ans = 0;
182+
for (int i = 0; i < n; ++i) {
183+
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
184+
}
185+
return ans;
186+
};
187+
188+
ll x = calc(nums);
189+
reverse(nums.begin(), nums.end());
190+
ll y = calc(nums);
191+
ll s = accumulate(nums.begin(), nums.end(), 0LL);
192+
return static_cast<int>((x + y + s) % mod);
193+
}
194+
};
93195
```
94196

95197
#### Go
96198

97199
```go
98-
200+
func getSum(nums []int) int {
201+
const mod = 1e9 + 7
202+
203+
calc := func(nums []int) int64 {
204+
n := len(nums)
205+
left := make([]int64, n)
206+
right := make([]int64, n)
207+
cnt := make(map[int]int64)
208+
209+
for i := 1; i < n; i++ {
210+
cnt[nums[i-1]] += 1 + cnt[nums[i-1]-1]
211+
left[i] = cnt[nums[i]-1]
212+
}
213+
214+
cnt = make(map[int]int64)
215+
216+
for i := n - 2; i >= 0; i-- {
217+
cnt[nums[i+1]] += 1 + cnt[nums[i+1]+1]
218+
right[i] = cnt[nums[i]+1]
219+
}
220+
221+
var ans int64
222+
for i, x := range nums {
223+
ans = (ans + (left[i]+right[i]+(left[i]*right[i]%mod))*int64(x)%mod) % mod
224+
}
225+
return ans
226+
}
227+
228+
x := calc(nums)
229+
for i, j := 0, len(nums)-1; i < j; i, j = i+1, j-1 {
230+
nums[i], nums[j] = nums[j], nums[i]
231+
}
232+
y := calc(nums)
233+
s := int64(0)
234+
for _, num := range nums {
235+
s += int64(num)
236+
}
237+
return int((x + y + s) % mod)
238+
}
99239
```
100240

101241
<!-- tabs:end -->
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Solution {
2+
public:
3+
int getSum(vector<int>& nums) {
4+
using ll = long long;
5+
const int mod = 1e9 + 7;
6+
auto calc = [&](const vector<int>& nums) -> ll {
7+
int n = nums.size();
8+
vector<ll> left(n), right(n);
9+
unordered_map<int, ll> cnt;
10+
11+
for (int i = 1; i < n; ++i) {
12+
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1];
13+
left[i] = cnt[nums[i] - 1];
14+
}
15+
16+
cnt.clear();
17+
18+
for (int i = n - 2; i >= 0; --i) {
19+
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1];
20+
right[i] = cnt[nums[i] + 1];
21+
}
22+
23+
ll ans = 0;
24+
for (int i = 0; i < n; ++i) {
25+
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
26+
}
27+
return ans;
28+
};
29+
30+
ll x = calc(nums);
31+
reverse(nums.begin(), nums.end());
32+
ll y = calc(nums);
33+
ll s = accumulate(nums.begin(), nums.end(), 0LL);
34+
return static_cast<int>((x + y + s) % mod);
35+
}
36+
};

0 commit comments

Comments
 (0)