|
| 1 | +--- |
| 2 | +comments: true |
| 3 | +difficulty: 中等 |
| 4 | +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3284.Sum%20of%20Consecutive%20Subarrays/README.md |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- problem:start --> |
| 8 | + |
| 9 | +# [3284. Sum of Consecutive Subarrays 🔒](https://leetcode.cn/problems/sum-of-consecutive-subarrays) |
| 10 | + |
| 11 | +[English Version](/solution/3200-3299/3284.Sum%20of%20Consecutive%20Subarrays/README_EN.md) |
| 12 | + |
| 13 | +## 题目描述 |
| 14 | + |
| 15 | +<!-- description:start --> |
| 16 | + |
| 17 | +<p>We call an array <code>arr</code> of length <code>n</code> <strong>consecutive</strong> if one of the following holds:</p> |
| 18 | + |
| 19 | +<ul> |
| 20 | + <li><code>arr[i] - arr[i - 1] == 1</code> for <em>all</em> <code>1 <= i < n</code>.</li> |
| 21 | + <li><code>arr[i] - arr[i - 1] == -1</code> for <em>all</em> <code>1 <= i < n</code>.</li> |
| 22 | +</ul> |
| 23 | + |
| 24 | +<p>The <strong>value</strong> of an array is the sum of its elements.</p> |
| 25 | + |
| 26 | +<p>For example, <code>[3, 4, 5]</code> is a consecutive array of value 12 and <code>[9, 8]</code> is another of value 17. While <code>[3, 4, 3]</code> and <code>[8, 6]</code> are not consecutive.</p> |
| 27 | + |
| 28 | +<p>Given an array of integers <code>nums</code>, return the <em>sum</em> of the <strong>values</strong> of all <strong>consecutive </strong><span data-keyword="subarray-nonempty">subarrays</span>.</p> |
| 29 | + |
| 30 | +<p>Since the answer may be very large, return it <strong>modulo</strong> <code>10<sup>9 </sup>+ 7.</code></p> |
| 31 | + |
| 32 | +<p><strong>Note</strong> that an array of length 1 is also considered consecutive.</p> |
| 33 | + |
| 34 | +<p> </p> |
| 35 | +<p><strong class="example">Example 1:</strong></p> |
| 36 | + |
| 37 | +<div class="example-block"> |
| 38 | +<p><strong>Input:</strong> <span class="example-io">nums = [1,2,3]</span></p> |
| 39 | + |
| 40 | +<p><strong>Output:</strong> <span class="example-io">20</span></p> |
| 41 | + |
| 42 | +<p><strong>Explanation:</strong></p> |
| 43 | + |
| 44 | +<p>The consecutive subarrays are: <code>[1]</code>, <code>[2]</code>, <code>[3]</code>, <code>[1, 2]</code>, <code>[2, 3]</code>, <code>[1, 2, 3]</code>.<br /> |
| 45 | +Sum of their values would be: <code>1 + 2 + 3 + 3 + 5 + 6 = 20</code>.</p> |
| 46 | +</div> |
| 47 | + |
| 48 | +<p><strong class="example">Example 2:</strong></p> |
| 49 | + |
| 50 | +<div class="example-block"> |
| 51 | +<p><strong>Input:</strong> <span class="example-io">nums = [1,3,5,7]</span></p> |
| 52 | + |
| 53 | +<p><strong>Output:</strong> <span class="example-io">16</span></p> |
| 54 | + |
| 55 | +<p><strong>Explanation:</strong></p> |
| 56 | + |
| 57 | +<p>The consecutive subarrays are: <code>[1]</code>, <code>[3]</code>, <code>[5]</code>, <code>[7]</code>.<br /> |
| 58 | +Sum of their values would be: <code>1 + 3 + 5 + 7 = 16</code>.</p> |
| 59 | +</div> |
| 60 | + |
| 61 | +<p><strong class="example">Example 3:</strong></p> |
| 62 | + |
| 63 | +<div class="example-block"> |
| 64 | +<p><strong>Input:</strong> <span class="example-io">nums = [7,6,1,2]</span></p> |
| 65 | + |
| 66 | +<p><strong>Output:</strong> <span class="example-io">32</span></p> |
| 67 | + |
| 68 | +<p><strong>Explanation:</strong></p> |
| 69 | + |
| 70 | +<p>The consecutive subarrays are: <code>[7]</code>, <code>[6]</code>, <code>[1]</code>, <code>[2]</code>, <code>[7, 6]</code>, <code>[1, 2]</code>.<br /> |
| 71 | +Sum of their values would be: <code>7 + 6 + 1 + 2 + 13 + 3 = 32</code>.</p> |
| 72 | +</div> |
| 73 | + |
| 74 | +<p> </p> |
| 75 | +<p><strong>Constraints:</strong></p> |
| 76 | + |
| 77 | +<ul> |
| 78 | + <li><code>1 <= nums.length <= 10<sup>5</sup></code></li> |
| 79 | + <li><code>1 <= nums[i] <= 10<sup>5</sup></code></li> |
| 80 | +</ul> |
| 81 | + |
| 82 | +<!-- description:end --> |
| 83 | + |
| 84 | +## 解法 |
| 85 | + |
| 86 | +<!-- solution:start --> |
| 87 | + |
| 88 | +### 方法一:递推 |
| 89 | + |
| 90 | +我们定义两个变量 $f$ 和 $g$,分别表示以当前元素结尾的递增子数组的长度和以当前元素结尾的递减子数组的长度,用另外两个变量 $s$ 和 $t$ 分别表示以当前元素结尾的递增子数组的和和以当前元素结尾的递减子数组的和。初始时 $f = g = 1$,而 $s = t = \textit{nums}[0]$。 |
| 91 | + |
| 92 | +接下来,我们从第二个元素开始遍历数组,对于当前元素 $\textit{nums}[i]$,我们分别考虑以 $\textit{nums}[i]$ 结尾的递增子数组和递减子数组。 |
| 93 | + |
| 94 | +如果 $\textit{nums}[i] - \textit{nums}[i - 1] = 1$,那么 $\textit{nums}[i]$ 可以加入到以 $\textit{nums}[i - 1]$ 结尾的递增子数组中,此时我们更新 $f$ 和 $s$,并将 $s$ 加到答案中; |
| 95 | + |
| 96 | +如果 $\textit{nums}[i] - \textit{nums}[i - 1] = -1$,那么 $\textit{nums}[i]$ 可以加入到以 $\textit{nums}[i - 1]$ 结尾的递减子数组中,此时我们更新 $g$ 和 $t$,并将 $t$ 加到答案中。 |
| 97 | + |
| 98 | +否则,$\textit{nums}[i]$ 无法加入到以 $\textit{nums}[i - 1]$ 结尾的递增子数组或递减子数组中,我们将 $\textit{nums}[i]$ 加到答案中。 |
| 99 | + |
| 100 | +遍历结束后,返回答案即可。 |
| 101 | + |
| 102 | +时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。 |
| 103 | + |
| 104 | +<!-- tabs:start --> |
| 105 | + |
| 106 | +#### Python3 |
| 107 | + |
| 108 | +```python |
| 109 | +class Solution: |
| 110 | + def getSum(self, nums: List[int]) -> int: |
| 111 | + mod = 10**9 + 7 |
| 112 | + f = g = 1 |
| 113 | + s = t = nums[0] |
| 114 | + ans = nums[0] |
| 115 | + for x, y in pairwise(nums): |
| 116 | + if y - x == 1: |
| 117 | + f += 1 |
| 118 | + s += f * y |
| 119 | + ans = (ans + s) % mod |
| 120 | + else: |
| 121 | + f = 1 |
| 122 | + s = y |
| 123 | + if y - x == -1: |
| 124 | + g += 1 |
| 125 | + t += g * y |
| 126 | + ans = (ans + t) % mod |
| 127 | + else: |
| 128 | + g = 1 |
| 129 | + t = y |
| 130 | + if abs(y - x) != 1: |
| 131 | + ans = (ans + y) % mod |
| 132 | + return ans |
| 133 | +``` |
| 134 | + |
| 135 | +#### Java |
| 136 | + |
| 137 | +```java |
| 138 | +class Solution { |
| 139 | + public int getSum(int[] nums) { |
| 140 | + final int mod = (int) 1e9 + 7; |
| 141 | + long s = nums[0], t = nums[0], ans = nums[0]; |
| 142 | + int f = 1, g = 1; |
| 143 | + for (int i = 1; i < nums.length; ++i) { |
| 144 | + int x = nums[i - 1], y = nums[i]; |
| 145 | + if (y - x == 1) { |
| 146 | + ++f; |
| 147 | + s += 1L * f * y; |
| 148 | + ans = (ans + s) % mod; |
| 149 | + } else { |
| 150 | + f = 1; |
| 151 | + s = y; |
| 152 | + } |
| 153 | + if (y - x == -1) { |
| 154 | + ++g; |
| 155 | + t += 1L * g * y; |
| 156 | + ans = (ans + t) % mod; |
| 157 | + } else { |
| 158 | + g = 1; |
| 159 | + t = y; |
| 160 | + } |
| 161 | + if (Math.abs(y - x) != 1) { |
| 162 | + ans = (ans + y) % mod; |
| 163 | + } |
| 164 | + } |
| 165 | + return (int) ans; |
| 166 | + } |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +#### C++ |
| 171 | + |
| 172 | +```cpp |
| 173 | +class Solution { |
| 174 | +public: |
| 175 | + int getSum(vector<int>& nums) { |
| 176 | + const int mod = 1e9 + 7; |
| 177 | + long long s = nums[0], t = nums[0], ans = nums[0]; |
| 178 | + int f = 1, g = 1; |
| 179 | + for (int i = 1; i < nums.size(); ++i) { |
| 180 | + int x = nums[i - 1], y = nums[i]; |
| 181 | + if (y - x == 1) { |
| 182 | + ++f; |
| 183 | + s += 1LL * f * y; |
| 184 | + ans = (ans + s) % mod; |
| 185 | + } else { |
| 186 | + f = 1; |
| 187 | + s = y; |
| 188 | + } |
| 189 | + if (y - x == -1) { |
| 190 | + ++g; |
| 191 | + t += 1LL * g * y; |
| 192 | + ans = (ans + t) % mod; |
| 193 | + } else { |
| 194 | + g = 1; |
| 195 | + t = y; |
| 196 | + } |
| 197 | + if (abs(y - x) != 1) { |
| 198 | + ans = (ans + y) % mod; |
| 199 | + } |
| 200 | + } |
| 201 | + return ans; |
| 202 | + } |
| 203 | +}; |
| 204 | +``` |
| 205 | +
|
| 206 | +#### Go |
| 207 | +
|
| 208 | +```go |
| 209 | +func getSum(nums []int) int { |
| 210 | + const mod int = 1e9 + 7 |
| 211 | + f, g := 1, 1 |
| 212 | + s, t := nums[0], nums[0] |
| 213 | + ans := nums[0] |
| 214 | +
|
| 215 | + for i := 1; i < len(nums); i++ { |
| 216 | + x, y := nums[i-1], nums[i] |
| 217 | +
|
| 218 | + if y-x == 1 { |
| 219 | + f++ |
| 220 | + s += f * y |
| 221 | + ans = (ans + s) % mod |
| 222 | + } else { |
| 223 | + f = 1 |
| 224 | + s = y |
| 225 | + } |
| 226 | +
|
| 227 | + if y-x == -1 { |
| 228 | + g++ |
| 229 | + t += g * y |
| 230 | + ans = (ans + t) % mod |
| 231 | + } else { |
| 232 | + g = 1 |
| 233 | + t = y |
| 234 | + } |
| 235 | +
|
| 236 | + if abs(y-x) != 1 { |
| 237 | + ans = (ans + y) % mod |
| 238 | + } |
| 239 | + } |
| 240 | +
|
| 241 | + return ans |
| 242 | +} |
| 243 | +
|
| 244 | +func abs(x int) int { |
| 245 | + if x < 0 { |
| 246 | + return -x |
| 247 | + } |
| 248 | + return x |
| 249 | +} |
| 250 | +``` |
| 251 | + |
| 252 | +#### TypeScript |
| 253 | + |
| 254 | +```ts |
| 255 | +function getSum(nums: number[]): number { |
| 256 | + const mod = 10 ** 9 + 7; |
| 257 | + let f = 1, |
| 258 | + g = 1; |
| 259 | + let s = nums[0], |
| 260 | + t = nums[0]; |
| 261 | + let ans = nums[0]; |
| 262 | + |
| 263 | + for (let i = 1; i < nums.length; i++) { |
| 264 | + const x = nums[i - 1]; |
| 265 | + const y = nums[i]; |
| 266 | + |
| 267 | + if (y - x === 1) { |
| 268 | + f++; |
| 269 | + s += f * y; |
| 270 | + ans = (ans + s) % mod; |
| 271 | + } else { |
| 272 | + f = 1; |
| 273 | + s = y; |
| 274 | + } |
| 275 | + |
| 276 | + if (y - x === -1) { |
| 277 | + g++; |
| 278 | + t += g * y; |
| 279 | + ans = (ans + t) % mod; |
| 280 | + } else { |
| 281 | + g = 1; |
| 282 | + t = y; |
| 283 | + } |
| 284 | + |
| 285 | + if (Math.abs(y - x) !== 1) { |
| 286 | + ans = (ans + y) % mod; |
| 287 | + } |
| 288 | + } |
| 289 | + |
| 290 | + return ans; |
| 291 | +} |
| 292 | +``` |
| 293 | + |
| 294 | +<!-- tabs:end --> |
| 295 | + |
| 296 | +<!-- solution:end --> |
| 297 | + |
| 298 | +<!-- problem:end --> |
0 commit comments