|
42 | 42 |
|
43 | 43 | <!-- 这里可写通用的实现逻辑 -->
|
44 | 44 |
|
| 45 | +**方法一:滑动窗口** |
| 46 | + |
45 | 47 | 滑动窗口,枚举第三个子数组的位置,同时维护前两个无重叠子数组的最大和及其位置。
|
46 | 48 |
|
| 49 | +时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 |
| 50 | + |
| 51 | +**方法二:预处理前后缀 + 枚举中间子数组** |
| 52 | + |
| 53 | +我们可以预处理得到数组 $nums$ 的前缀和数组 $s$,其中 $s[i] = \sum_{j=0}^{i-1} nums[j]$,那么对于任意的 $i$,$j$,$s[j] - s[i]$ 就是子数组 $[i, j)$ 的和。 |
| 54 | + |
| 55 | +接下来,我们使用动态规划的方法,维护两个长度为 $n$ 的数组 $pre$ 和 $suf$,其中 $pre[i]$ 表示 $[0, i]$ 范围内长度为 $k$ 的子数组的最大和及其起始位置,$suf[i]$ 表示 $[i, n)$ 范围内长度为 $k$ 的子数组的最大和及其起始位置。 |
| 56 | + |
| 57 | +然后,我们枚举中间子数组的起始位置 $i$,那么三个子数组的和就是 $pre[i-1][0] + suf[i+k][0] + (s[i+k] - s[i])$,其中 $pre[i-1][0]$ 表示 $[0, i-1]$ 范围内长度为 $k$ 的子数组的最大和,$suf[i+k][0]$ 表示 $[i+k, n)$ 范围内长度为 $k$ 的子数组的最大和,$(s[i+k] - s[i])$ 表示 $[i, i+k)$ 范围内长度为 $k$ 的子数组的和。我们找出和的最大值对应的三个子数组的起始位置即可。 |
| 58 | + |
| 59 | +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。 |
| 60 | + |
47 | 61 | <!-- tabs:start -->
|
48 | 62 |
|
49 | 63 | ### **Python3**
|
@@ -77,6 +91,36 @@ class Solution:
|
77 | 91 | return ans
|
78 | 92 | ```
|
79 | 93 |
|
| 94 | +```python |
| 95 | +class Solution: |
| 96 | + def maxSumOfThreeSubarrays(self, nums: List[int], k: int) -> List[int]: |
| 97 | + n = len(nums) |
| 98 | + s = list(accumulate(nums, initial=0)) |
| 99 | + pre = [[] for _ in range(n)] |
| 100 | + suf = [[] for _ in range(n)] |
| 101 | + t = idx = 0 |
| 102 | + for i in range(n - k + 1): |
| 103 | + if (cur := s[i + k] - s[i]) > t: |
| 104 | + pre[i + k - 1] = [cur, i] |
| 105 | + t, idx = pre[i + k - 1] |
| 106 | + else: |
| 107 | + pre[i + k - 1] = [t, idx] |
| 108 | + t = idx = 0 |
| 109 | + for i in range(n - k, -1, -1): |
| 110 | + if (cur := s[i + k] - s[i]) >= t: |
| 111 | + suf[i] = [cur, i] |
| 112 | + t, idx = suf[i] |
| 113 | + else: |
| 114 | + suf[i] = [t, idx] |
| 115 | + t = 0 |
| 116 | + ans = [] |
| 117 | + for i in range(k, n - 2 * k + 1): |
| 118 | + if (cur := s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]) > t: |
| 119 | + ans = [pre[i - 1][1], i, suf[i + k][1]] |
| 120 | + t = cur |
| 121 | + return ans |
| 122 | +``` |
| 123 | + |
80 | 124 | ### **Java**
|
81 | 125 |
|
82 | 126 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
@@ -116,6 +160,49 @@ class Solution {
|
116 | 160 | }
|
117 | 161 | ```
|
118 | 162 |
|
| 163 | +```java |
| 164 | +class Solution { |
| 165 | + public int[] maxSumOfThreeSubarrays(int[] nums, int k) { |
| 166 | + int n = nums.length; |
| 167 | + int[] s = new int[n + 1]; |
| 168 | + for (int i = 0; i < n; ++i) { |
| 169 | + s[i + 1] = s[i] + nums[i]; |
| 170 | + } |
| 171 | + int[][] pre = new int[n][0]; |
| 172 | + int[][] suf = new int[n][0]; |
| 173 | + for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) { |
| 174 | + int cur = s[i + k] - s[i]; |
| 175 | + if (cur > t) { |
| 176 | + pre[i + k - 1] = new int[] {cur, i}; |
| 177 | + t = cur; |
| 178 | + idx = i; |
| 179 | + } else { |
| 180 | + pre[i + k - 1] = new int[] {t, idx}; |
| 181 | + } |
| 182 | + } |
| 183 | + for (int i = n - k, t = 0, idx = 0; i >= 0; --i) { |
| 184 | + int cur = s[i + k] - s[i]; |
| 185 | + if (cur >= t) { |
| 186 | + suf[i] = new int[] {cur, i}; |
| 187 | + t = cur; |
| 188 | + idx = i; |
| 189 | + } else { |
| 190 | + suf[i] = new int[] {t, idx}; |
| 191 | + } |
| 192 | + } |
| 193 | + int[] ans = new int[0]; |
| 194 | + for (int i = k, t = 0; i < n - 2 * k + 1; ++i) { |
| 195 | + int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]; |
| 196 | + if (cur > t) { |
| 197 | + ans = new int[] {pre[i - 1][1], i, suf[i + k][1]}; |
| 198 | + t = cur; |
| 199 | + } |
| 200 | + } |
| 201 | + return ans; |
| 202 | + } |
| 203 | +} |
| 204 | +``` |
| 205 | + |
119 | 206 | ### **C++**
|
120 | 207 |
|
121 | 208 | ```cpp
|
@@ -154,6 +241,55 @@ public:
|
154 | 241 | };
|
155 | 242 | ```
|
156 | 243 |
|
| 244 | +```cpp |
| 245 | +class Solution { |
| 246 | +public: |
| 247 | + vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) { |
| 248 | + int n = nums.size(); |
| 249 | + vector<int> s(n + 1, 0); |
| 250 | + for (int i = 0; i < n; ++i) { |
| 251 | + s[i + 1] = s[i] + nums[i]; |
| 252 | + } |
| 253 | +
|
| 254 | + vector<vector<int>> pre(n, vector<int>(2, 0)); |
| 255 | + vector<vector<int>> suf(n, vector<int>(2, 0)); |
| 256 | +
|
| 257 | + for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) { |
| 258 | + int cur = s[i + k] - s[i]; |
| 259 | + if (cur > t) { |
| 260 | + pre[i + k - 1] = {cur, i}; |
| 261 | + t = cur; |
| 262 | + idx = i; |
| 263 | + } else { |
| 264 | + pre[i + k - 1] = {t, idx}; |
| 265 | + } |
| 266 | + } |
| 267 | +
|
| 268 | + for (int i = n - k, t = 0, idx = 0; i >= 0; --i) { |
| 269 | + int cur = s[i + k] - s[i]; |
| 270 | + if (cur >= t) { |
| 271 | + suf[i] = {cur, i}; |
| 272 | + t = cur; |
| 273 | + idx = i; |
| 274 | + } else { |
| 275 | + suf[i] = {t, idx}; |
| 276 | + } |
| 277 | + } |
| 278 | +
|
| 279 | + vector<int> ans; |
| 280 | + for (int i = k, t = 0; i < n - 2 * k + 1; ++i) { |
| 281 | + int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]; |
| 282 | + if (cur > t) { |
| 283 | + ans = {pre[i - 1][1], i, suf[i + k][1]}; |
| 284 | + t = cur; |
| 285 | + } |
| 286 | + } |
| 287 | +
|
| 288 | + return ans; |
| 289 | + } |
| 290 | +}; |
| 291 | +``` |
| 292 | + |
157 | 293 | ### **Go**
|
158 | 294 |
|
159 | 295 | ```go
|
@@ -189,6 +325,102 @@ func maxSumOfThreeSubarrays(nums []int, k int) []int {
|
189 | 325 | }
|
190 | 326 | ```
|
191 | 327 |
|
| 328 | +```go |
| 329 | +func maxSumOfThreeSubarrays(nums []int, k int) (ans []int) { |
| 330 | + n := len(nums) |
| 331 | + s := make([]int, n+1) |
| 332 | + for i := 0; i < n; i++ { |
| 333 | + s[i+1] = s[i] + nums[i] |
| 334 | + } |
| 335 | + |
| 336 | + pre := make([][]int, n) |
| 337 | + suf := make([][]int, n) |
| 338 | + |
| 339 | + for i, t, idx := 0, 0, 0; i < n-k+1; i++ { |
| 340 | + cur := s[i+k] - s[i] |
| 341 | + if cur > t { |
| 342 | + pre[i+k-1] = []int{cur, i} |
| 343 | + t, idx = cur, i |
| 344 | + } else { |
| 345 | + pre[i+k-1] = []int{t, idx} |
| 346 | + } |
| 347 | + } |
| 348 | + |
| 349 | + for i, t, idx := n-k, 0, 0; i >= 0; i-- { |
| 350 | + cur := s[i+k] - s[i] |
| 351 | + if cur >= t { |
| 352 | + suf[i] = []int{cur, i} |
| 353 | + t, idx = cur, i |
| 354 | + } else { |
| 355 | + suf[i] = []int{t, idx} |
| 356 | + } |
| 357 | + } |
| 358 | + |
| 359 | + for i, t := k, 0; i < n-2*k+1; i++ { |
| 360 | + cur := s[i+k] - s[i] + pre[i-1][0] + suf[i+k][0] |
| 361 | + if cur > t { |
| 362 | + ans = []int{pre[i-1][1], i, suf[i+k][1]} |
| 363 | + t = cur |
| 364 | + } |
| 365 | + } |
| 366 | + |
| 367 | + return |
| 368 | +} |
| 369 | +``` |
| 370 | + |
| 371 | +### **TypeScript** |
| 372 | + |
| 373 | +```ts |
| 374 | +function maxSumOfThreeSubarrays(nums: number[], k: number): number[] { |
| 375 | + const n: number = nums.length; |
| 376 | + const s: number[] = Array(n + 1).fill(0); |
| 377 | + |
| 378 | + for (let i = 0; i < n; ++i) { |
| 379 | + s[i + 1] = s[i] + nums[i]; |
| 380 | + } |
| 381 | + |
| 382 | + const pre: number[][] = Array(n) |
| 383 | + .fill([]) |
| 384 | + .map(() => new Array(2).fill(0)); |
| 385 | + const suf: number[][] = Array(n) |
| 386 | + .fill([]) |
| 387 | + .map(() => new Array(2).fill(0)); |
| 388 | + |
| 389 | + for (let i = 0, t = 0, idx = 0; i < n - k + 1; ++i) { |
| 390 | + const cur: number = s[i + k] - s[i]; |
| 391 | + if (cur > t) { |
| 392 | + pre[i + k - 1] = [cur, i]; |
| 393 | + t = cur; |
| 394 | + idx = i; |
| 395 | + } else { |
| 396 | + pre[i + k - 1] = [t, idx]; |
| 397 | + } |
| 398 | + } |
| 399 | + |
| 400 | + for (let i = n - k, t = 0, idx = 0; i >= 0; --i) { |
| 401 | + const cur: number = s[i + k] - s[i]; |
| 402 | + if (cur >= t) { |
| 403 | + suf[i] = [cur, i]; |
| 404 | + t = cur; |
| 405 | + idx = i; |
| 406 | + } else { |
| 407 | + suf[i] = [t, idx]; |
| 408 | + } |
| 409 | + } |
| 410 | + |
| 411 | + let ans: number[] = []; |
| 412 | + for (let i = k, t = 0; i < n - 2 * k + 1; ++i) { |
| 413 | + const cur: number = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]; |
| 414 | + if (cur > t) { |
| 415 | + ans = [pre[i - 1][1], i, suf[i + k][1]]; |
| 416 | + t = cur; |
| 417 | + } |
| 418 | + } |
| 419 | + |
| 420 | + return ans; |
| 421 | +} |
| 422 | +``` |
| 423 | + |
192 | 424 | ### **...**
|
193 | 425 |
|
194 | 426 | ```
|
|
0 commit comments