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

feat: add solutions to lc problem: No.0689 #1982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,22 @@

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

**方法一:滑动窗口**

滑动窗口,枚举第三个子数组的位置,同时维护前两个无重叠子数组的最大和及其位置。

时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。

**方法二:预处理前后缀 + 枚举中间子数组**

我们可以预处理得到数组 $nums$ 的前缀和数组 $s$,其中 $s[i] = \sum_{j=0}^{i-1} nums[j]$,那么对于任意的 $i$,$j$,$s[j] - s[i]$ 就是子数组 $[i, j)$ 的和。

接下来,我们使用动态规划的方法,维护两个长度为 $n$ 的数组 $pre$ 和 $suf$,其中 $pre[i]$ 表示 $[0, i]$ 范围内长度为 $k$ 的子数组的最大和及其起始位置,$suf[i]$ 表示 $[i, n)$ 范围内长度为 $k$ 的子数组的最大和及其起始位置。

然后,我们枚举中间子数组的起始位置 $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$ 的子数组的和。我们找出和的最大值对应的三个子数组的起始位置即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -77,6 +91,36 @@ class Solution:
return ans
```

```python
class Solution:
def maxSumOfThreeSubarrays(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
s = list(accumulate(nums, initial=0))
pre = [[] for _ in range(n)]
suf = [[] for _ in range(n)]
t = idx = 0
for i in range(n - k + 1):
if (cur := s[i + k] - s[i]) > t:
pre[i + k - 1] = [cur, i]
t, idx = pre[i + k - 1]
else:
pre[i + k - 1] = [t, idx]
t = idx = 0
for i in range(n - k, -1, -1):
if (cur := s[i + k] - s[i]) >= t:
suf[i] = [cur, i]
t, idx = suf[i]
else:
suf[i] = [t, idx]
t = 0
ans = []
for i in range(k, n - 2 * k + 1):
if (cur := s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0]) > t:
ans = [pre[i - 1][1], i, suf[i + k][1]]
t = cur
return ans
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->
Expand Down Expand Up @@ -116,6 +160,49 @@ class Solution {
}
```

```java
class Solution {
public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
int n = nums.length;
int[] s = new int[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
int[][] pre = new int[n][0];
int[][] suf = new int[n][0];
for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
int cur = s[i + k] - s[i];
if (cur > t) {
pre[i + k - 1] = new int[] {cur, i};
t = cur;
idx = i;
} else {
pre[i + k - 1] = new int[] {t, idx};
}
}
for (int i = n - k, t = 0, idx = 0; i >= 0; --i) {
int cur = s[i + k] - s[i];
if (cur >= t) {
suf[i] = new int[] {cur, i};
t = cur;
idx = i;
} else {
suf[i] = new int[] {t, idx};
}
}
int[] ans = new int[0];
for (int i = k, t = 0; i < n - 2 * k + 1; ++i) {
int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
if (cur > t) {
ans = new int[] {pre[i - 1][1], i, suf[i + k][1]};
t = cur;
}
}
return ans;
}
}
```

### **C++**

```cpp
Expand Down Expand Up @@ -154,6 +241,55 @@ public:
};
```

```cpp
class Solution {
public:
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
int n = nums.size();
vector<int> s(n + 1, 0);
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}

vector<vector<int>> pre(n, vector<int>(2, 0));
vector<vector<int>> suf(n, vector<int>(2, 0));

for (int i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
int cur = s[i + k] - s[i];
if (cur > t) {
pre[i + k - 1] = {cur, i};
t = cur;
idx = i;
} else {
pre[i + k - 1] = {t, idx};
}
}

for (int i = n - k, t = 0, idx = 0; i >= 0; --i) {
int cur = s[i + k] - s[i];
if (cur >= t) {
suf[i] = {cur, i};
t = cur;
idx = i;
} else {
suf[i] = {t, idx};
}
}

vector<int> ans;
for (int i = k, t = 0; i < n - 2 * k + 1; ++i) {
int cur = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
if (cur > t) {
ans = {pre[i - 1][1], i, suf[i + k][1]};
t = cur;
}
}

return ans;
}
};
```

### **Go**

```go
Expand Down Expand Up @@ -189,6 +325,102 @@ func maxSumOfThreeSubarrays(nums []int, k int) []int {
}
```

```go
func maxSumOfThreeSubarrays(nums []int, k int) (ans []int) {
n := len(nums)
s := make([]int, n+1)
for i := 0; i < n; i++ {
s[i+1] = s[i] + nums[i]
}

pre := make([][]int, n)
suf := make([][]int, n)

for i, t, idx := 0, 0, 0; i < n-k+1; i++ {
cur := s[i+k] - s[i]
if cur > t {
pre[i+k-1] = []int{cur, i}
t, idx = cur, i
} else {
pre[i+k-1] = []int{t, idx}
}
}

for i, t, idx := n-k, 0, 0; i >= 0; i-- {
cur := s[i+k] - s[i]
if cur >= t {
suf[i] = []int{cur, i}
t, idx = cur, i
} else {
suf[i] = []int{t, idx}
}
}

for i, t := k, 0; i < n-2*k+1; i++ {
cur := s[i+k] - s[i] + pre[i-1][0] + suf[i+k][0]
if cur > t {
ans = []int{pre[i-1][1], i, suf[i+k][1]}
t = cur
}
}

return
}
```

### **TypeScript**

```ts
function maxSumOfThreeSubarrays(nums: number[], k: number): number[] {
const n: number = nums.length;
const s: number[] = Array(n + 1).fill(0);

for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}

const pre: number[][] = Array(n)
.fill([])
.map(() => new Array(2).fill(0));
const suf: number[][] = Array(n)
.fill([])
.map(() => new Array(2).fill(0));

for (let i = 0, t = 0, idx = 0; i < n - k + 1; ++i) {
const cur: number = s[i + k] - s[i];
if (cur > t) {
pre[i + k - 1] = [cur, i];
t = cur;
idx = i;
} else {
pre[i + k - 1] = [t, idx];
}
}

for (let i = n - k, t = 0, idx = 0; i >= 0; --i) {
const cur: number = s[i + k] - s[i];
if (cur >= t) {
suf[i] = [cur, i];
t = cur;
idx = i;
} else {
suf[i] = [t, idx];
}
}

let ans: number[] = [];
for (let i = k, t = 0; i < n - 2 * k + 1; ++i) {
const cur: number = s[i + k] - s[i] + pre[i - 1][0] + suf[i + k][0];
if (cur > t) {
ans = [pre[i - 1][1], i, suf[i + k][1]];
t = cur;
}
}

return ans;
}
```

### **...**

```
Expand Down
Loading