From 5555477650da9de5fc11a019e2b552e59e1434cd Mon Sep 17 00:00:00 2001 From: qqpp13465 <1817138431@qq.com> Date: Mon, 11 May 2026 14:42:41 +0800 Subject: [PATCH 01/16] feat: add solution for 3915 --- .../README.md | 228 +++++++++++++++++- .../README_EN.md | 211 +++++++++++++++- .../Soluion.go | 49 ++++ .../Solution.cpp | 54 +++++ .../Solution.java | 71 ++++++ .../Solution.py | 43 ++++ 6 files changed, 648 insertions(+), 8 deletions(-) create mode 100644 solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go create mode 100644 solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp create mode 100644 solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java create mode 100644 solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md index 6f9505c51dede..c95358c3c79c9 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md @@ -104,6 +104,13 @@ source: 第 499 场周赛 Q4 ## 解法 +设 f(i,0) 表示以 i 结尾、且最后一步为谷(下一步要上升)的最大子序列和,f(i,1) 表示以 i 结尾、且最后一步为峰(下一步要下降)的最大子序列和。 + +转移时需要从满足 j≤i−k 的位置 j 转移: + +f(i,0):从 f(j,1) 转移,要求 nums[j] > nums[i],即查询值域中 nums[i] 右侧的最大 f(∗,1) 值。 +f(i,1):从 f(j,0) 转移,要求 nums[j] < nums[i],即查询值域中 nums[i] 左侧的最大 f(∗,0) 值。 +动态的前/后缀最大值可以用树状数组快速维护。由于只有 j≤i−k 的位置才能参与转移,我们可以用一个指针控制目前已经有哪些元素加入到树状数组中。复杂度 O(nlogn)。 ### 方法一 @@ -112,25 +119,238 @@ source: 第 499 场周赛 Q4 #### Python3 ```python - +class FenwickTree: + def __init__(self, n): + self.n = n + self.tree = [0]*(n+1) + + def update(self, index: int, val: int) -> None: + while index <= self.n: + self.tree[index] = max(self.tree[index], val) + index += (index&(-index)) # 往后更新 + + def preSum(self, pos): + # 按照预期的方式求前缀最大值 + ans = 0 + while pos >= 1: + ans = max(ans, self.tree[pos]) + pos -= (pos&(-pos)) + return ans + +class Solution: + def maxAlternatingSum(self, nums: list[int], k: int) -> int: + stl = sorted(set(nums)) # 将nums中不同的数字进行排序 + rank = {v:i+1 for i,v in enumerate(stl)} # 将nums中的值快速转换成stl中的索引 + fwt0 = FenwickTree(len(stl)) + fwt1 = FenwickTree(len(stl)) + + n = len(nums) + dp = [[0,0] for _ in range(n)] + res = nums[0] + for i in range(n): + dp[i][0] = dp[i][1] = nums[i] + if i >= k: + indx = rank[nums[i]] # 找到nums[i]在stl中的索引 + dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) # indx-1即表示小于nums[i]的部分 + dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 + + if i-k+1 >= 0: + indx = rank[nums[i-k+1]] + fwt0.update(indx, dp[i-k+1][0]) # 在正序列表中更新i-k+1位置的值 + fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) # 在倒序列表中更新i-k+1位置的值 + + res = max(res, dp[i][0], dp[i][1]) # 更新答案 + + return res ``` #### Java ```java - +class Solution { + public long maxAlternatingSum(int[] nums, int k) { + long maxSum = 0; + int n = nums.length; + int m = Arrays.stream(nums).max().getAsInt(); + long[][] dp = new long[n][2]; + SegmentTree[] sts = new SegmentTree[2]; + for (int j = 0; j < 2; j++) { + sts[j] = new SegmentTree(m + 1); + } + for (int i = 0; i < n; i++) { + if (i >= k) { + sts[0].update(nums[i - k], dp[i - k][0]); + sts[1].update(nums[i - k], dp[i - k][1]); + } + dp[i][0] = sts[1].getMax(0, nums[i] - 1) + nums[i]; + dp[i][1] = sts[0].getMax(nums[i] + 1, m) + nums[i]; + maxSum = Math.max(maxSum, Math.max(dp[i][0], dp[i][1])); + } + return maxSum; + } +} + +class SegmentTree { + private int n; + private long[] tree; + + public SegmentTree(int n) { + this.n = n; + this.tree = new long[n * 4]; + } + + public long getMax(int start, int end) { + return getMax(start, end, 0, 0, n - 1); + } + + public void update(int index, long value) { + update(index, value, 0, 0, n - 1); + } + + private long getMax(int rangeStart, int rangeEnd, int treeIndex, int treeStart, int treeEnd) { + if (rangeStart > rangeEnd) { + return 0; + } + if (rangeStart == treeStart && rangeEnd == treeEnd) { + return tree[treeIndex]; + } + int mid = treeStart + (treeEnd - treeStart) / 2; + if (rangeEnd <= mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 1, treeStart, mid); + } else if (rangeStart > mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd); + } else { + return Math.max(getMax(rangeStart, mid, treeIndex * 2 + 1, treeStart, mid), getMax(mid + 1, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd)); + } + } + + private void update(int rangeIndex, long value, int treeIndex, int start, int end) { + if (start == end) { + tree[treeIndex] = value; + return; + } + int mid = start + (end - start) / 2; + if (rangeIndex <= mid) { + update(rangeIndex, value, treeIndex * 2 + 1, start, mid); + } else { + update(rangeIndex, value, treeIndex * 2 + 2, mid + 1, end); + } + tree[treeIndex] = Math.max(tree[treeIndex * 2 + 1], tree[treeIndex * 2 + 2]); + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long maxAlternatingSum(vector& nums, int K) { + int n = nums.size(); + + // 离散化 + int idx[n]; + map mp; + for (int x : nums) mp[x] = 1; + int m = 0; + for (auto &p : mp) p.second = ++m; + for (int i = 0; i < n; i++) idx[i] = mp[nums[i]]; + + const long long INF = 1e18; + // tree[0]:前缀最大值(用于查询 < nums[i] 的最大 f[j][0]) + // tree[1]:后缀最大值(用于查询 > nums[i] 的最大 f[j][1]) + long long tree[2][m + 1]; + for (int i = 0; i < 2; i++) for (int j = 0; j <= m; j++) tree[i][j] = -INF; + + // 树状数组模板开始 + + auto lb = [&](int x) { return x & (-x); }; + + auto update = [&](long long *tree, int pos, long long val) { + for (; pos <= m; pos += lb(pos)) tree[pos] = max(tree[pos], val); + }; + + auto query = [&](long long *tree, int pos) { + long long ret = -INF; + for (; pos; pos -= lb(pos)) ret = max(ret, tree[pos]); + return ret; + }; + + // 树状数组模板结束 + + long long ans = 0; + long long f[n + 1][2]; + for (int i = 0; i <= n; i++) for (int j = 0; j < 2; j++) f[i][j] = -INF; + // 滑动窗口:只有 j <= i - K 的位置才加入树状数组 + for (int i = 1, j = 1; i <= n; i++) { + while (i - j >= K) { + update(tree[0], idx[j - 1], f[j][0]); + update(tree[1], m + 1 - idx[j - 1], f[j][1]); + j++; + } + // 谷:从 tree[1] 查询值 > nums[i] 的最大 f[j][1] + f[i][0] = max(0LL, query(tree[1], m - idx[i - 1])) + nums[i - 1]; + // 峰:从 tree[0] 查询值 < nums[i] 的最大 f[j][0] + f[i][1] = max(0LL, query(tree[0], idx[i - 1] - 1)) + nums[i - 1]; + ans = max({ans, f[i][0], f[i][1]}); + } + return ans; + } +}; ``` #### Go ```go - +type fenwick []int64 + +func (f fenwick) update(i int, val int64) { + for ; i < len(f); i += i & -i { + f[i] = max(f[i], val) + } +} + +// [1, i] 中的最大值 +func (f fenwick) preMax(i int) (res int64) { + for ; i > 0; i &= i - 1 { + res = max(res, f[i]) + } + return +} + +func maxAlternatingSum(nums []int, k int) (ans int64) { + // 离散化 nums + sorted := slices.Clone(nums) + slices.Sort(sorted) + sorted = slices.Compact(sorted) + + n := len(nums) + fInc := make([]int64, n) // fInc[i] 表示以 nums[i] 结尾且最后两项递增的交替子序列的最大和 + fDec := make([]int64, n) // fDec[i] 表示以 nums[i] 结尾且最后两项递减的交替子序列的最大和 + + // 值域树状数组 + m := len(sorted) + inc := make(fenwick, m+1) // 维护 fInc[i] 的最大值 + dec := make(fenwick, m+1) // 维护 fDec[i] 的最大值 + + for i, x := range nums { + if i >= k { + // 在这个时候才把 fInc[i-k] 和 fDec[i-k] 添加到值域树状数组中,从而保证转移来源的下标 <= i-k + j := nums[i-k] + inc.update(m-j, fInc[i-k]) // m-j 可以把后缀变成前缀 + dec.update(j+1, fDec[i-k]) + } + + j := sort.SearchInts(sorted, x) + nums[i] = j // 注意这里修改了 nums[i],这样上面的 nums[i-k] 无需二分 + + fInc[i] = dec.preMax(j) + int64(x) // 计算满足 nums[i'] < x 的 fDec[i'] 的最大值 + fDec[i] = inc.preMax(m-1-j) + int64(x) // 计算满足 nums[i'] > x 的 fInc[i'] 的最大值 + ans = max(ans, fInc[i], fDec[i]) // 枚举子序列以 nums[i] 结尾 + } + + return +} ``` diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md index 8ed2e8e30fd66..7f822f2cfaf0d 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md @@ -99,6 +99,9 @@ source: Weekly Contest 499 Q4 ## Solutions +Let f(i,0) denote the maximum subsequence sum ending at i and whose last step is a valley (indicating an increase in the next step), and let f(i,1) denote the maximum subsequence sum ending at i and whose last step is a peak (indicating a decrease in the next step). +During the transfer, it is necessary to transfer from a position j that satisfies j ≤ i − k: +f(i,0): Transferred from f(j,1), requiring nums[j] > nums[i], i.e., querying the maximum f(∗,1) value on the right side of nums[i] in the value domain. f(i,1): Transferred from f(j,0), requiring nums[j] < nums[i], i.e., querying the maximum f(∗,0) value on the left side of nums[i] in the value domain. Dynamic prefix/suffix maximum values can be quickly maintained using a tree-like array. Since only positions where j ≤ i−k can participate in the transfer, we can use a pointer to control which elements have been added to the tree-like array so far. Complexity: O(nlogn). ### Solution 1 @@ -107,25 +110,225 @@ source: Weekly Contest 499 Q4 #### Python3 ```python - +class FenwickTree: + def __init__(self, n): + self.n = n + self.tree = [0]*(n+1) + + def update(self, index: int, val: int) -> None: + while index <= self.n: + self.tree[index] = max(self.tree[index], val) + index += (index&(-index)) + + def preSum(self, pos): + ans = 0 + while pos >= 1: + ans = max(ans, self.tree[pos]) + pos -= (pos&(-pos)) + return ans + +class Solution: + def maxAlternatingSum(self, nums: list[int], k: int) -> int: + stl = sorted(set(nums)) + rank = {v:i+1 for i,v in enumerate(stl)} + fwt0 = FenwickTree(len(stl)) + fwt1 = FenwickTree(len(stl)) + + n = len(nums) + dp = [[0,0] for _ in range(n)] + res = nums[0] + for i in range(n): + dp[i][0] = dp[i][1] = nums[i] + if i >= k: + indx = rank[nums[i]] + dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) + dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) + + if i-k+1 >= 0: + indx = rank[nums[i-k+1]] + fwt0.update(indx, dp[i-k+1][0]) + fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) + + res = max(res, dp[i][0], dp[i][1]) + + return res ``` #### Java ```java - +class Solution { + public long maxAlternatingSum(int[] nums, int k) { + long maxSum = 0; + int n = nums.length; + int m = Arrays.stream(nums).max().getAsInt(); + long[][] dp = new long[n][2]; + SegmentTree[] sts = new SegmentTree[2]; + for (int j = 0; j < 2; j++) { + sts[j] = new SegmentTree(m + 1); + } + for (int i = 0; i < n; i++) { + if (i >= k) { + sts[0].update(nums[i - k], dp[i - k][0]); + sts[1].update(nums[i - k], dp[i - k][1]); + } + dp[i][0] = sts[1].getMax(0, nums[i] - 1) + nums[i]; + dp[i][1] = sts[0].getMax(nums[i] + 1, m) + nums[i]; + maxSum = Math.max(maxSum, Math.max(dp[i][0], dp[i][1])); + } + return maxSum; + } +} + +class SegmentTree { + private int n; + private long[] tree; + + public SegmentTree(int n) { + this.n = n; + this.tree = new long[n * 4]; + } + + public long getMax(int start, int end) { + return getMax(start, end, 0, 0, n - 1); + } + + public void update(int index, long value) { + update(index, value, 0, 0, n - 1); + } + + private long getMax(int rangeStart, int rangeEnd, int treeIndex, int treeStart, int treeEnd) { + if (rangeStart > rangeEnd) { + return 0; + } + if (rangeStart == treeStart && rangeEnd == treeEnd) { + return tree[treeIndex]; + } + int mid = treeStart + (treeEnd - treeStart) / 2; + if (rangeEnd <= mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 1, treeStart, mid); + } else if (rangeStart > mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd); + } else { + return Math.max(getMax(rangeStart, mid, treeIndex * 2 + 1, treeStart, mid), getMax(mid + 1, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd)); + } + } + + private void update(int rangeIndex, long value, int treeIndex, int start, int end) { + if (start == end) { + tree[treeIndex] = value; + return; + } + int mid = start + (end - start) / 2; + if (rangeIndex <= mid) { + update(rangeIndex, value, treeIndex * 2 + 1, start, mid); + } else { + update(rangeIndex, value, treeIndex * 2 + 2, mid + 1, end); + } + tree[treeIndex] = Math.max(tree[treeIndex * 2 + 1], tree[treeIndex * 2 + 2]); + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long maxAlternatingSum(vector& nums, int K) { + int n = nums.size(); + + int idx[n]; + map mp; + for (int x : nums) mp[x] = 1; + int m = 0; + for (auto &p : mp) p.second = ++m; + for (int i = 0; i < n; i++) idx[i] = mp[nums[i]]; + + const long long INF = 1e18; + long long tree[2][m + 1]; + for (int i = 0; i < 2; i++) for (int j = 0; j <= m; j++) tree[i][j] = -INF; + + + auto lb = [&](int x) { return x & (-x); }; + + auto update = [&](long long *tree, int pos, long long val) { + for (; pos <= m; pos += lb(pos)) tree[pos] = max(tree[pos], val); + }; + + auto query = [&](long long *tree, int pos) { + long long ret = -INF; + for (; pos; pos -= lb(pos)) ret = max(ret, tree[pos]); + return ret; + }; + + + long long ans = 0; + long long f[n + 1][2]; + for (int i = 0; i <= n; i++) for (int j = 0; j < 2; j++) f[i][j] = -INF; + for (int i = 1, j = 1; i <= n; i++) { + while (i - j >= K) { + update(tree[0], idx[j - 1], f[j][0]); + update(tree[1], m + 1 - idx[j - 1], f[j][1]); + j++; + } + f[i][0] = max(0LL, query(tree[1], m - idx[i - 1])) + nums[i - 1]; + f[i][1] = max(0LL, query(tree[0], idx[i - 1] - 1)) + nums[i - 1]; + ans = max({ans, f[i][0], f[i][1]}); + } + return ans; + } +}; ``` #### Go ```go - +type fenwick []int64 + +func (f fenwick) update(i int, val int64) { + for ; i < len(f); i += i & -i { + f[i] = max(f[i], val) + } +} + +func (f fenwick) preMax(i int) (res int64) { + for ; i > 0; i &= i - 1 { + res = max(res, f[i]) + } + return +} + +func maxAlternatingSum(nums []int, k int) (ans int64) { + sorted := slices.Clone(nums) + slices.Sort(sorted) + sorted = slices.Compact(sorted) + + n := len(nums) + fInc := make([]int64, n) + fDec := make([]int64, n) + + m := len(sorted) + inc := make(fenwick, m+1) + dec := make(fenwick, m+1) + + for i, x := range nums { + if i >= k { + j := nums[i-k] + inc.update(m-j, fInc[i-k]) + dec.update(j+1, fDec[i-k]) + } + + j := sort.SearchInts(sorted, x) + nums[i] = j + + fInc[i] = dec.preMax(j) + int64(x) + fDec[i] = inc.preMax(m-1-j) + int64(x) + ans = max(ans, fInc[i], fDec[i]) + } + + return +} ``` diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go new file mode 100644 index 0000000000000..eb4a8011fada9 --- /dev/null +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go @@ -0,0 +1,49 @@ +type fenwick []int64 + +func (f fenwick) update(i int, val int64) { + for ; i < len(f); i += i & -i { + f[i] = max(f[i], val) + } +} + +// [1, i] 中的最大值 +func (f fenwick) preMax(i int) (res int64) { + for ; i > 0; i &= i - 1 { + res = max(res, f[i]) + } + return +} + +func maxAlternatingSum(nums []int, k int) (ans int64) { + // 离散化 nums + sorted := slices.Clone(nums) + slices.Sort(sorted) + sorted = slices.Compact(sorted) + + n := len(nums) + fInc := make([]int64, n) // fInc[i] 表示以 nums[i] 结尾且最后两项递增的交替子序列的最大和 + fDec := make([]int64, n) // fDec[i] 表示以 nums[i] 结尾且最后两项递减的交替子序列的最大和 + + // 值域树状数组 + m := len(sorted) + inc := make(fenwick, m+1) // 维护 fInc[i] 的最大值 + dec := make(fenwick, m+1) // 维护 fDec[i] 的最大值 + + for i, x := range nums { + if i >= k { + // 在这个时候才把 fInc[i-k] 和 fDec[i-k] 添加到值域树状数组中,从而保证转移来源的下标 <= i-k + j := nums[i-k] + inc.update(m-j, fInc[i-k]) // m-j 可以把后缀变成前缀 + dec.update(j+1, fDec[i-k]) + } + + j := sort.SearchInts(sorted, x) + nums[i] = j // 注意这里修改了 nums[i],这样上面的 nums[i-k] 无需二分 + + fInc[i] = dec.preMax(j) + int64(x) // 计算满足 nums[i'] < x 的 fDec[i'] 的最大值 + fDec[i] = inc.preMax(m-1-j) + int64(x) // 计算满足 nums[i'] > x 的 fInc[i'] 的最大值 + ans = max(ans, fInc[i], fDec[i]) // 枚举子序列以 nums[i] 结尾 + } + + return +} \ No newline at end of file diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp new file mode 100644 index 0000000000000..b3b3268ebc7be --- /dev/null +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp @@ -0,0 +1,54 @@ +class Solution { +public: + long long maxAlternatingSum(vector& nums, int K) { + int n = nums.size(); + + // 离散化 + int idx[n]; + map mp; + for (int x : nums) mp[x] = 1; + int m = 0; + for (auto &p : mp) p.second = ++m; + for (int i = 0; i < n; i++) idx[i] = mp[nums[i]]; + + const long long INF = 1e18; + // tree[0]:前缀最大值(用于查询 < nums[i] 的最大 f[j][0]) + // tree[1]:后缀最大值(用于查询 > nums[i] 的最大 f[j][1]) + long long tree[2][m + 1]; + for (int i = 0; i < 2; i++) for (int j = 0; j <= m; j++) tree[i][j] = -INF; + + // 树状数组模板开始 + + auto lb = [&](int x) { return x & (-x); }; + + auto update = [&](long long *tree, int pos, long long val) { + for (; pos <= m; pos += lb(pos)) tree[pos] = max(tree[pos], val); + }; + + auto query = [&](long long *tree, int pos) { + long long ret = -INF; + for (; pos; pos -= lb(pos)) ret = max(ret, tree[pos]); + return ret; + }; + + // 树状数组模板结束 + + long long ans = 0; + long long f[n + 1][2]; + for (int i = 0; i <= n; i++) for (int j = 0; j < 2; j++) f[i][j] = -INF; + // 滑动窗口:只有 j <= i - K 的位置才加入树状数组 + for (int i = 1, j = 1; i <= n; i++) { + while (i - j >= K) { + update(tree[0], idx[j - 1], f[j][0]); + update(tree[1], m + 1 - idx[j - 1], f[j][1]); + j++; + } + // 谷:从 tree[1] 查询值 > nums[i] 的最大 f[j][1] + f[i][0] = max(0LL, query(tree[1], m - idx[i - 1])) + nums[i - 1]; + // 峰:从 tree[0] 查询值 < nums[i] 的最大 f[j][0] + f[i][1] = max(0LL, query(tree[0], idx[i - 1] - 1)) + nums[i - 1]; + ans = max({ans, f[i][0], f[i][1]}); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java new file mode 100644 index 0000000000000..c1cd3678fa18b --- /dev/null +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java @@ -0,0 +1,71 @@ +class Solution { + public long maxAlternatingSum(int[] nums, int k) { + long maxSum = 0; + int n = nums.length; + int m = Arrays.stream(nums).max().getAsInt(); + long[][] dp = new long[n][2]; + SegmentTree[] sts = new SegmentTree[2]; + for (int j = 0; j < 2; j++) { + sts[j] = new SegmentTree(m + 1); + } + for (int i = 0; i < n; i++) { + if (i >= k) { + sts[0].update(nums[i - k], dp[i - k][0]); + sts[1].update(nums[i - k], dp[i - k][1]); + } + dp[i][0] = sts[1].getMax(0, nums[i] - 1) + nums[i]; + dp[i][1] = sts[0].getMax(nums[i] + 1, m) + nums[i]; + maxSum = Math.max(maxSum, Math.max(dp[i][0], dp[i][1])); + } + return maxSum; + } +} + +class SegmentTree { + private int n; + private long[] tree; + + public SegmentTree(int n) { + this.n = n; + this.tree = new long[n * 4]; + } + + public long getMax(int start, int end) { + return getMax(start, end, 0, 0, n - 1); + } + + public void update(int index, long value) { + update(index, value, 0, 0, n - 1); + } + + private long getMax(int rangeStart, int rangeEnd, int treeIndex, int treeStart, int treeEnd) { + if (rangeStart > rangeEnd) { + return 0; + } + if (rangeStart == treeStart && rangeEnd == treeEnd) { + return tree[treeIndex]; + } + int mid = treeStart + (treeEnd - treeStart) / 2; + if (rangeEnd <= mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 1, treeStart, mid); + } else if (rangeStart > mid) { + return getMax(rangeStart, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd); + } else { + return Math.max(getMax(rangeStart, mid, treeIndex * 2 + 1, treeStart, mid), getMax(mid + 1, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd)); + } + } + + private void update(int rangeIndex, long value, int treeIndex, int start, int end) { + if (start == end) { + tree[treeIndex] = value; + return; + } + int mid = start + (end - start) / 2; + if (rangeIndex <= mid) { + update(rangeIndex, value, treeIndex * 2 + 1, start, mid); + } else { + update(rangeIndex, value, treeIndex * 2 + 2, mid + 1, end); + } + tree[treeIndex] = Math.max(tree[treeIndex * 2 + 1], tree[treeIndex * 2 + 2]); + } +} \ No newline at end of file diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py new file mode 100644 index 0000000000000..9e2916e28b787 --- /dev/null +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py @@ -0,0 +1,43 @@ +class FenwickTree: + def __init__(self, n): + self.n = n + self.tree = [0]*(n+1) + + def update(self, index: int, val: int) -> None: + while index <= self.n: + self.tree[index] = max(self.tree[index], val) + index += (index&(-index)) # 往后更新 + + def preSum(self, pos): + # 按照预期的方式求前缀最大值 + ans = 0 + while pos >= 1: + ans = max(ans, self.tree[pos]) + pos -= (pos&(-pos)) + return ans + +class Solution: + def maxAlternatingSum(self, nums: list[int], k: int) -> int: + stl = sorted(set(nums)) # 将nums中不同的数字进行排序 + rank = {v:i+1 for i,v in enumerate(stl)} # 将nums中的值快速转换成stl中的索引 + fwt0 = FenwickTree(len(stl)) + fwt1 = FenwickTree(len(stl)) + + n = len(nums) + dp = [[0,0] for _ in range(n)] + res = nums[0] + for i in range(n): + dp[i][0] = dp[i][1] = nums[i] + if i >= k: + indx = rank[nums[i]] # 找到nums[i]在stl中的索引 + dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) # indx-1即表示小于nums[i]的部分 + dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 + + if i-k+1 >= 0: + indx = rank[nums[i-k+1]] + fwt0.update(indx, dp[i-k+1][0]) # 在正序列表中更新i-k+1位置的值 + fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) # 在倒序列表中更新i-k+1位置的值 + + res = max(res, dp[i][0], dp[i][1]) # 更新答案 + + return res \ No newline at end of file From 07355bd56e0a7dfae5d6f87c62dd2628604d944f Mon Sep 17 00:00:00 2001 From: qqpp13465 <1817138431@qq.com> Date: Mon, 11 May 2026 18:34:33 +0800 Subject: [PATCH 02/16] feat: add solution for 3916 --- .../README.md | 53 ++++++++++++++++-- .../README_EN.md | 54 +++++++++++++++++-- .../Solution.cpp | 14 +++++ .../Solution.go | 11 ++++ .../Solution.java | 13 +++++ .../Solution.py | 10 ++++ 6 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp create mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go create mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java create mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md b/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md index 21b341bcda0f3..3c24f2d883683 100644 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md @@ -79,6 +79,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu ## 解法 +从右到左遍历 nums,维护遍历过的奇数个数和偶数个数。根据 nums[i] 的奇偶性,查询其右侧的偶数个数或奇数个数。 ### 方法一 @@ -87,25 +88,69 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu #### Python3 ```python - +class Solution: + def countOppositeParity(self, nums: list[int]) -> list[int]: + n = len(nums) + ans = [0] * n + cnt = [0] * 2 + for i in range(n - 1, -1, -1): + x = nums[i] % 2 # x 的奇偶性 + ans[i] = cnt[1 - x] # 查询右侧奇偶性不等于 x 的元素个数 + cnt[x] += 1 + return ans ``` #### Java ```java - +class Solution { + public int[] countOppositeParity(int[] nums) { + int n = nums.length; + int[] ans = new int[n]; + int[] cnt = new int[2]; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; // x 的奇偶性 + ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector countOppositeParity(vector& nums) { + int n = nums.size(); + vector ans(n); + int cnt[2]{}; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; // x 的奇偶性 + ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++; + } + return ans; + } +}; ``` #### Go ```go - +func countOppositeParity(nums []int) []int { + n := len(nums) + ans := make([]int, n) + cnt := [2]int{} + for i := n - 1; i >= 0; i-- { + x := nums[i] & 1 // x 的奇偶性 + ans[i] = cnt[x^1] // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++ + } + return ans +} ``` diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md b/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md index 0b529816523e6..6de0e409ee256 100644 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md @@ -79,7 +79,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu ## Solutions - +Traverse nums from right to left, maintaining the count of odd and even numbers that have been traversed. Based on the parity of nums[i], query the count of even or odd numbers to its right. ### Solution 1 @@ -87,25 +87,69 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu #### Python3 ```python - +class Solution: + def countOppositeParity(self, nums: list[int]) -> list[int]: + n = len(nums) + ans = [0] * n + cnt = [0] * 2 + for i in range(n - 1, -1, -1): + x = nums[i] % 2 + ans[i] = cnt[1 - x] + cnt[x] += 1 + return ans ``` #### Java ```java - +class Solution { + public int[] countOppositeParity(int[] nums) { + int n = nums.length; + int[] ans = new int[n]; + int[] cnt = new int[2]; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; + ans[i] = cnt[x ^ 1]; + cnt[x]++; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector countOppositeParity(vector& nums) { + int n = nums.size(); + vector ans(n); + int cnt[2]{}; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; + ans[i] = cnt[x ^ 1]; + cnt[x]++; + } + return ans; + } +}; ``` #### Go ```go - +func countOppositeParity(nums []int) []int { + n := len(nums) + ans := make([]int, n) + cnt := [2]int{} + for i := n - 1; i >= 0; i-- { + x := nums[i] & 1 + ans[i] = cnt[x^1] + cnt[x]++ + } + return ans +} ``` diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp new file mode 100644 index 0000000000000..b55a2c50869f6 --- /dev/null +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + vector countOppositeParity(vector& nums) { + int n = nums.size(); + vector ans(n); + int cnt[2]{}; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; // x 的奇偶性 + ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go new file mode 100644 index 0000000000000..341596d4c8aac --- /dev/null +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go @@ -0,0 +1,11 @@ +func countOppositeParity(nums []int) []int { + n := len(nums) + ans := make([]int, n) + cnt := [2]int{} + for i := n - 1; i >= 0; i-- { + x := nums[i] & 1 // x 的奇偶性 + ans[i] = cnt[x^1] // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++ + } + return ans +} \ No newline at end of file diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java new file mode 100644 index 0000000000000..7452bc2f15760 --- /dev/null +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java @@ -0,0 +1,13 @@ +class Solution { + public int[] countOppositeParity(int[] nums) { + int n = nums.length; + int[] ans = new int[n]; + int[] cnt = new int[2]; + for (int i = n - 1; i >= 0; i--) { + int x = nums[i] & 1; // x 的奇偶性 + ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 + cnt[x]++; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py new file mode 100644 index 0000000000000..77f8f665ee196 --- /dev/null +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py @@ -0,0 +1,10 @@ +class Solution: + def countOppositeParity(self, nums: list[int]) -> list[int]: + n = len(nums) + ans = [0] * n + cnt = [0] * 2 + for i in range(n - 1, -1, -1): + x = nums[i] % 2 # x 的奇偶性 + ans[i] = cnt[1 - x] # 查询右侧奇偶性不等于 x 的元素个数 + cnt[x] += 1 + return ans \ No newline at end of file From c627df8de9faba505f0077f9f63f65d2effd3d27 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:36:49 +0800 Subject: [PATCH 03/16] Rename Soluion.go to Solution.go --- .../{Soluion.go => Solution.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/{Soluion.go => Solution.go} (99%) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.go similarity index 99% rename from solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go rename to solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.go index eb4a8011fada9..d53a1fd815c3d 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Soluion.go +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.go @@ -46,4 +46,4 @@ func maxAlternatingSum(nums []int, k int) (ans int64) { } return -} \ No newline at end of file +} From 8b13461e5e12b35879e0842c5d7bb7f53cb00938 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:48:28 +0800 Subject: [PATCH 04/16] Enhance README with dynamic programming solution details Updated the README with detailed explanations of the dynamic programming approach and state transitions for the maximum sum of alternating subsequences problem. --- .../README.md | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md index c95358c3c79c9..aca1f22bff209 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md @@ -104,15 +104,37 @@ source: 第 499 场周赛 Q4 ## 解法 -设 f(i,0) 表示以 i 结尾、且最后一步为谷(下一步要上升)的最大子序列和,f(i,1) 表示以 i 结尾、且最后一步为峰(下一步要下降)的最大子序列和。 -转移时需要从满足 j≤i−k 的位置 j 转移: +### 方法一:动态规划 + 树状数组 -f(i,0):从 f(j,1) 转移,要求 nums[j] > nums[i],即查询值域中 nums[i] 右侧的最大 f(∗,1) 值。 -f(i,1):从 f(j,0) 转移,要求 nums[j] < nums[i],即查询值域中 nums[i] 左侧的最大 f(∗,0) 值。 -动态的前/后缀最大值可以用树状数组快速维护。由于只有 j≤i−k 的位置才能参与转移,我们可以用一个指针控制目前已经有哪些元素加入到树状数组中。复杂度 O(nlogn)。 +**状态定义** -### 方法一 +定义 $f[i][0]$ 表示以下标 $i$ 结尾、且末位元素为**谷**(需要下一个更大才符合交替)的合法子序列最大和;$f[i][1]$ 表示以下标 $i$ 结尾、且末位元素为**峰**(需要下一个更小才符合交替)的合法子序列最大和。 + +**状态转移** + +转移时枚举满足 $j \leq i - k$ 的前驱下标 $j$: + +- 状态 $f[i][0]$(谷):由 $f[j][1]$ 转移,需要 $\text{nums}[j] > \text{nums}[i]$,即查询值域 $(\text{nums}[i],\ +\infty)$ 上 $f[\cdot][1]$ 的最大值: + +$$f[i][0] = \text{nums}[i] + \max\!\left(0,\ \max_{\substack{j \leq i-k \\ \text{nums}[j] > \text{nums}[i]}} f[j][1]\right)$$ + +- 状态 $f[i][1]$(峰):由 $f[j][0]$ 转移,需要 $\text{nums}[j] < \text{nums}[i]$,即查询值域 $[1,\ \text{nums}[i]-1]$ 上 $f[\cdot][0]$ 的最大值: + +$$f[i][1] = \text{nums}[i] + \max\!\left(0,\ \max_{\substack{j \leq i-k \\ \text{nums}[j] < \text{nums}[i]}} f[j][0]\right)$$ + +最终答案为 $\max_{0 \leq i < n}\max(f[i][0],\ f[i][1])$。 + +**优化** + +上述转移涉及动态的值域前缀/后缀最大值查询,可以用两棵**树状数组**维护: + +- 树状数组 $\text{bit}_0$:以值为下标,维护 $f[\cdot][0]$ 的前缀最大值,用于查询 $\text{nums}[j] < \text{nums}[i]$ 的情况。 +- 树状数组 $\text{bit}_1$:以 $M + 1 - \text{val}$(其中 $M = \max(\text{nums})$)为倒置下标,维护 $f[\cdot][1]$ 的前缀最大值,等价于值域上的后缀最大值,用于查询 $\text{nums}[j] > \text{nums}[i]$ 的情况。 + +为了保证只有 $j \leq i - k$ 的下标才能参与转移,在处理第 $i$ 个元素时,将第 $i - k$ 个元素的状态加入树状数组。 + +时间复杂度 $O(n \log M)$,空间复杂度 $O(M)$,其中 $n$ 为数组长度,而 $M = \max(\text{nums})$。 From 5a112017a85f1b6e243bf025a2e48ef411f8d6ca Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:51:16 +0800 Subject: [PATCH 05/16] Enhance README with detailed solution explanation Expanded the explanation of the dynamic programming solution and introduced the use of Binary Indexed Trees for optimization. --- .../README_EN.md | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md index 7f822f2cfaf0d..fc5e3ad4cd916 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md @@ -99,11 +99,37 @@ source: Weekly Contest 499 Q4 ## Solutions -Let f(i,0) denote the maximum subsequence sum ending at i and whose last step is a valley (indicating an increase in the next step), and let f(i,1) denote the maximum subsequence sum ending at i and whose last step is a peak (indicating a decrease in the next step). -During the transfer, it is necessary to transfer from a position j that satisfies j ≤ i − k: -f(i,0): Transferred from f(j,1), requiring nums[j] > nums[i], i.e., querying the maximum f(∗,1) value on the right side of nums[i] in the value domain. f(i,1): Transferred from f(j,0), requiring nums[j] < nums[i], i.e., querying the maximum f(∗,0) value on the left side of nums[i] in the value domain. Dynamic prefix/suffix maximum values can be quickly maintained using a tree-like array. Since only positions where j ≤ i−k can participate in the transfer, we can use a pointer to control which elements have been added to the tree-like array so far. Complexity: O(nlogn). -### Solution 1 +### Solution 1: Dynamic Programming + Binary Indexed Tree + +**State Definition** + +Let $f[i][0]$ denote the maximum sum of a valid subsequence ending at index $i$ where the last element is a **valley** (the next element must be larger to maintain alternation), and $f[i][1]$ denote the maximum sum where the last element is a **peak** (the next element must be smaller). + +**Transitions** + +When transitioning, we enumerate a predecessor index $j$ satisfying $j \leq i - k$: + +- State $f[i][0]$ (valley): transitions from $f[j][1]$, requiring $\text{nums}[j] > \text{nums}[i]$, i.e., query the maximum $f[\cdot][1]$ over the value range $(\text{nums}[i],\ +\infty)$: + +$$f[i][0] = \text{nums}[i] + \max\!\left(0,\ \max_{\substack{j \leq i-k \\ \text{nums}[j] > \text{nums}[i]}} f[j][1]\right)$$ + +- State $f[i][1]$ (peak): transitions from $f[j][0]$, requiring $\text{nums}[j] < \text{nums}[i]$, i.e., query the maximum $f[\cdot][0]$ over the value range $[1,\ \text{nums}[i]-1]$: + +$$f[i][1] = \text{nums}[i] + \max\!\left(0,\ \max_{\substack{j \leq i-k \\ \text{nums}[j] < \text{nums}[i]}} f[j][0]\right)$$ + +The final answer is $\max_{0 \leq i < n}\max(f[i][0],\ f[i][1])$. + +**Optimization** + +The transitions involve dynamic prefix/suffix maximum queries over a value domain, which can be maintained efficiently with two **Binary Indexed Trees (BITs)**: + +- BIT $\text{bit}_0$: indexed by value, maintains the prefix maximum of $f[\cdot][0]$, used to query cases where $\text{nums}[j] < \text{nums}[i]$. +- BIT $\text{bit}_1$: indexed by $M + 1 - \text{val}$ (reversed, where $M = \max(\text{nums})$ ), maintains the prefix maximum of $f[\cdot][1]$, equivalent to a suffix maximum over the value domain, used to query cases where $\text{nums}[j] > \text{nums}[i]$. + +To ensure only indices $j \leq i - k$ participate in transitions, when processing index $i$, we insert the state of index $i - k$ into the BITs using a sliding pointer. + +The time complexity is $O(n \log M)$ and the space complexity is $O(M)$, where $n$ is the length of the array and $M = \max(\text{nums})$. From 3a51a78332b1c87783cc12b4ce83af49213e0d33 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:55:25 +0800 Subject: [PATCH 06/16] Delete solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java --- .../3916.Number of ZigZag Arrays III/Solution.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java deleted file mode 100644 index 7452bc2f15760..0000000000000 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.java +++ /dev/null @@ -1,13 +0,0 @@ -class Solution { - public int[] countOppositeParity(int[] nums) { - int n = nums.length; - int[] ans = new int[n]; - int[] cnt = new int[2]; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; // x 的奇偶性 - ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++; - } - return ans; - } -} \ No newline at end of file From 55260adfb845a024f000f5dfbb5debe5e7e4f20b Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:55:39 +0800 Subject: [PATCH 07/16] Delete solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp --- .../3916.Number of ZigZag Arrays III/Solution.cpp | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp deleted file mode 100644 index b55a2c50869f6..0000000000000 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.cpp +++ /dev/null @@ -1,14 +0,0 @@ -class Solution { -public: - vector countOppositeParity(vector& nums) { - int n = nums.size(); - vector ans(n); - int cnt[2]{}; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; // x 的奇偶性 - ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++; - } - return ans; - } -}; \ No newline at end of file From c7e1d0de9e9428d9be3671a61d356eda0140650f Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:55:52 +0800 Subject: [PATCH 08/16] Delete solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go --- .../3916.Number of ZigZag Arrays III/Solution.go | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go deleted file mode 100644 index 341596d4c8aac..0000000000000 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.go +++ /dev/null @@ -1,11 +0,0 @@ -func countOppositeParity(nums []int) []int { - n := len(nums) - ans := make([]int, n) - cnt := [2]int{} - for i := n - 1; i >= 0; i-- { - x := nums[i] & 1 // x 的奇偶性 - ans[i] = cnt[x^1] // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++ - } - return ans -} \ No newline at end of file From b6cfcdd34a60a749ddb7a3442fa05e523590ecd9 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:56:03 +0800 Subject: [PATCH 09/16] Delete solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py --- .../3916.Number of ZigZag Arrays III/Solution.py | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py b/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py deleted file mode 100644 index 77f8f665ee196..0000000000000 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/Solution.py +++ /dev/null @@ -1,10 +0,0 @@ -class Solution: - def countOppositeParity(self, nums: list[int]) -> list[int]: - n = len(nums) - ans = [0] * n - cnt = [0] * 2 - for i in range(n - 1, -1, -1): - x = nums[i] % 2 # x 的奇偶性 - ans[i] = cnt[1 - x] # 查询右侧奇偶性不等于 x 的元素个数 - cnt[x] += 1 - return ans \ No newline at end of file From 3215fb5acb4c0dd8129383bb3efa75d84b66fcf6 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:56:46 +0800 Subject: [PATCH 10/16] Remove code examples from README.md Removed code examples for Python, Java, C++, and Go from README. --- .../README.md | 53 ++----------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md b/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md index 3c24f2d883683..21b341bcda0f3 100644 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/README.md @@ -79,7 +79,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu ## 解法 -从右到左遍历 nums,维护遍历过的奇数个数和偶数个数。根据 nums[i] 的奇偶性,查询其右侧的偶数个数或奇数个数。 ### 方法一 @@ -88,69 +87,25 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu #### Python3 ```python -class Solution: - def countOppositeParity(self, nums: list[int]) -> list[int]: - n = len(nums) - ans = [0] * n - cnt = [0] * 2 - for i in range(n - 1, -1, -1): - x = nums[i] % 2 # x 的奇偶性 - ans[i] = cnt[1 - x] # 查询右侧奇偶性不等于 x 的元素个数 - cnt[x] += 1 - return ans + ``` #### Java ```java -class Solution { - public int[] countOppositeParity(int[] nums) { - int n = nums.length; - int[] ans = new int[n]; - int[] cnt = new int[2]; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; // x 的奇偶性 - ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++; - } - return ans; - } -} + ``` #### C++ ```cpp -class Solution { -public: - vector countOppositeParity(vector& nums) { - int n = nums.size(); - vector ans(n); - int cnt[2]{}; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; // x 的奇偶性 - ans[i] = cnt[x ^ 1]; // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++; - } - return ans; - } -}; + ``` #### Go ```go -func countOppositeParity(nums []int) []int { - n := len(nums) - ans := make([]int, n) - cnt := [2]int{} - for i := n - 1; i >= 0; i-- { - x := nums[i] & 1 // x 的奇偶性 - ans[i] = cnt[x^1] // 查询右侧奇偶性不等于 x(即 x^1)的元素个数 - cnt[x]++ - } - return ans -} + ``` From 0f2f0dc56fc776d461f4ac939f1c0a8f85f11170 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 18:57:25 +0800 Subject: [PATCH 11/16] Update README_EN.md --- .../README_EN.md | 54 ++----------------- 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md b/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md index 6de0e409ee256..0b529816523e6 100644 --- a/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md +++ b/solution/3900-3999/3916.Number of ZigZag Arrays III/README_EN.md @@ -79,7 +79,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3916.Nu ## Solutions -Traverse nums from right to left, maintaining the count of odd and even numbers that have been traversed. Based on the parity of nums[i], query the count of even or odd numbers to its right. + ### Solution 1 @@ -87,69 +87,25 @@ Traverse nums from right to left, maintaining the count of odd and even numbers #### Python3 ```python -class Solution: - def countOppositeParity(self, nums: list[int]) -> list[int]: - n = len(nums) - ans = [0] * n - cnt = [0] * 2 - for i in range(n - 1, -1, -1): - x = nums[i] % 2 - ans[i] = cnt[1 - x] - cnt[x] += 1 - return ans + ``` #### Java ```java -class Solution { - public int[] countOppositeParity(int[] nums) { - int n = nums.length; - int[] ans = new int[n]; - int[] cnt = new int[2]; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; - ans[i] = cnt[x ^ 1]; - cnt[x]++; - } - return ans; - } -} + ``` #### C++ ```cpp -class Solution { -public: - vector countOppositeParity(vector& nums) { - int n = nums.size(); - vector ans(n); - int cnt[2]{}; - for (int i = n - 1; i >= 0; i--) { - int x = nums[i] & 1; - ans[i] = cnt[x ^ 1]; - cnt[x]++; - } - return ans; - } -}; + ``` #### Go ```go -func countOppositeParity(nums []int) []int { - n := len(nums) - ans := make([]int, n) - cnt := [2]int{} - for i := n - 1; i >= 0; i-- { - x := nums[i] & 1 - ans[i] = cnt[x^1] - cnt[x]++ - } - return ans -} + ``` From 2ca9ba4c1d5ee85400a4faa5cbcda43a656c5205 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 19:03:33 +0800 Subject: [PATCH 12/16] Refactor Solution.py for clarity and consistency --- .../Solution.py | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py index 9e2916e28b787..e2c58c61ec7f8 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.py @@ -1,43 +1,52 @@ class FenwickTree: def __init__(self, n): self.n = n - self.tree = [0]*(n+1) + self.tree = [0] * (n + 1) def update(self, index: int, val: int) -> None: while index <= self.n: self.tree[index] = max(self.tree[index], val) - index += (index&(-index)) # 往后更新 + index += index & (-index) # 往后更新 def preSum(self, pos): # 按照预期的方式求前缀最大值 ans = 0 while pos >= 1: ans = max(ans, self.tree[pos]) - pos -= (pos&(-pos)) + pos -= pos & (-pos) return ans + class Solution: def maxAlternatingSum(self, nums: list[int], k: int) -> int: - stl = sorted(set(nums)) # 将nums中不同的数字进行排序 - rank = {v:i+1 for i,v in enumerate(stl)} # 将nums中的值快速转换成stl中的索引 + stl = sorted(set(nums)) # 将nums中不同的数字进行排序 + rank = { + v: i + 1 for i, v in enumerate(stl) + } # 将nums中的值快速转换成stl中的索引 fwt0 = FenwickTree(len(stl)) fwt1 = FenwickTree(len(stl)) - + n = len(nums) - dp = [[0,0] for _ in range(n)] + dp = [[0, 0] for _ in range(n)] res = nums[0] for i in range(n): dp[i][0] = dp[i][1] = nums[i] if i >= k: - indx = rank[nums[i]] # 找到nums[i]在stl中的索引 - dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) # indx-1即表示小于nums[i]的部分 - dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 - - if i-k+1 >= 0: - indx = rank[nums[i-k+1]] - fwt0.update(indx, dp[i-k+1][0]) # 在正序列表中更新i-k+1位置的值 - fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) # 在倒序列表中更新i-k+1位置的值 - - res = max(res, dp[i][0], dp[i][1]) # 更新答案 - - return res \ No newline at end of file + indx = rank[nums[i]] # 找到nums[i]在stl中的索引 + dp[i][1] = max( + dp[i][1], fwt0.preSum(indx - 1) + nums[i] + ) # indx-1即表示小于nums[i]的部分 + dp[i][0] = max( + dp[i][0], fwt1.preSum(len(stl) - indx) + nums[i] + ) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 + + if i - k + 1 >= 0: + indx = rank[nums[i - k + 1]] + fwt0.update(indx, dp[i - k + 1][0]) # 在正序列表中更新i-k+1位置的值 + fwt1.update( + len(stl) - indx + 1, dp[i - k + 1][1] + ) # 在倒序列表中更新i-k+1位置的值 + + res = max(res, dp[i][0], dp[i][1]) # 更新答案 + + return res From 8011ce895ff87a18123275304918968306cd4d04 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 19:04:22 +0800 Subject: [PATCH 13/16] Improve code formatting in README.md Refactor code for better readability and formatting. --- .../README.md | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md index aca1f22bff209..a7525a5c68a0c 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README.md @@ -144,44 +144,53 @@ $$f[i][1] = \text{nums}[i] + \max\!\left(0,\ \max_{\substack{j \leq i-k \\ \text class FenwickTree: def __init__(self, n): self.n = n - self.tree = [0]*(n+1) + self.tree = [0] * (n + 1) def update(self, index: int, val: int) -> None: while index <= self.n: self.tree[index] = max(self.tree[index], val) - index += (index&(-index)) # 往后更新 + index += index & (-index) # 往后更新 def preSum(self, pos): # 按照预期的方式求前缀最大值 ans = 0 while pos >= 1: ans = max(ans, self.tree[pos]) - pos -= (pos&(-pos)) + pos -= pos & (-pos) return ans + class Solution: def maxAlternatingSum(self, nums: list[int], k: int) -> int: - stl = sorted(set(nums)) # 将nums中不同的数字进行排序 - rank = {v:i+1 for i,v in enumerate(stl)} # 将nums中的值快速转换成stl中的索引 + stl = sorted(set(nums)) # 将nums中不同的数字进行排序 + rank = { + v: i + 1 for i, v in enumerate(stl) + } # 将nums中的值快速转换成stl中的索引 fwt0 = FenwickTree(len(stl)) fwt1 = FenwickTree(len(stl)) - + n = len(nums) - dp = [[0,0] for _ in range(n)] + dp = [[0, 0] for _ in range(n)] res = nums[0] for i in range(n): dp[i][0] = dp[i][1] = nums[i] if i >= k: - indx = rank[nums[i]] # 找到nums[i]在stl中的索引 - dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) # indx-1即表示小于nums[i]的部分 - dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 - - if i-k+1 >= 0: - indx = rank[nums[i-k+1]] - fwt0.update(indx, dp[i-k+1][0]) # 在正序列表中更新i-k+1位置的值 - fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) # 在倒序列表中更新i-k+1位置的值 - - res = max(res, dp[i][0], dp[i][1]) # 更新答案 + indx = rank[nums[i]] # 找到nums[i]在stl中的索引 + dp[i][1] = max( + dp[i][1], fwt0.preSum(indx - 1) + nums[i] + ) # indx-1即表示小于nums[i]的部分 + dp[i][0] = max( + dp[i][0], fwt1.preSum(len(stl) - indx) + nums[i] + ) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 + + if i - k + 1 >= 0: + indx = rank[nums[i - k + 1]] + fwt0.update(indx, dp[i - k + 1][0]) # 在正序列表中更新i-k+1位置的值 + fwt1.update( + len(stl) - indx + 1, dp[i - k + 1][1] + ) # 在倒序列表中更新i-k+1位置的值 + + res = max(res, dp[i][0], dp[i][1]) # 更新答案 return res ``` From 491de800d855bcd25f01c968b0515b1d3a93cfc5 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 19:15:29 +0800 Subject: [PATCH 14/16] Fix formatting and comments in README_EN.md --- .../README_EN.md | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md index fc5e3ad4cd916..e068d91e34989 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/README_EN.md @@ -139,43 +139,53 @@ The time complexity is $O(n \log M)$ and the space complexity is $O(M)$, where $ class FenwickTree: def __init__(self, n): self.n = n - self.tree = [0]*(n+1) + self.tree = [0] * (n + 1) def update(self, index: int, val: int) -> None: while index <= self.n: self.tree[index] = max(self.tree[index], val) - index += (index&(-index)) + index += index & (-index) # 往后更新 def preSum(self, pos): + # 按照预期的方式求前缀最大值 ans = 0 while pos >= 1: ans = max(ans, self.tree[pos]) - pos -= (pos&(-pos)) + pos -= pos & (-pos) return ans + class Solution: def maxAlternatingSum(self, nums: list[int], k: int) -> int: - stl = sorted(set(nums)) - rank = {v:i+1 for i,v in enumerate(stl)} + stl = sorted(set(nums)) # 将nums中不同的数字进行排序 + rank = { + v: i + 1 for i, v in enumerate(stl) + } # 将nums中的值快速转换成stl中的索引 fwt0 = FenwickTree(len(stl)) fwt1 = FenwickTree(len(stl)) - + n = len(nums) - dp = [[0,0] for _ in range(n)] + dp = [[0, 0] for _ in range(n)] res = nums[0] for i in range(n): dp[i][0] = dp[i][1] = nums[i] if i >= k: - indx = rank[nums[i]] - dp[i][1] = max(dp[i][1], fwt0.preSum(indx-1)+nums[i]) - dp[i][0] = max(dp[i][0], fwt1.preSum(len(stl)-indx)+nums[i]) - - if i-k+1 >= 0: - indx = rank[nums[i-k+1]] - fwt0.update(indx, dp[i-k+1][0]) - fwt1.update(len(stl)-indx+1, dp[i-k+1][1]) - - res = max(res, dp[i][0], dp[i][1]) + indx = rank[nums[i]] # 找到nums[i]在stl中的索引 + dp[i][1] = max( + dp[i][1], fwt0.preSum(indx - 1) + nums[i] + ) # indx-1即表示小于nums[i]的部分 + dp[i][0] = max( + dp[i][0], fwt1.preSum(len(stl) - indx) + nums[i] + ) # len(stl)-indx即表示在倒序列表中大于nums[i]的部分 + + if i - k + 1 >= 0: + indx = rank[nums[i - k + 1]] + fwt0.update(indx, dp[i - k + 1][0]) # 在正序列表中更新i-k+1位置的值 + fwt1.update( + len(stl) - indx + 1, dp[i - k + 1][1] + ) # 在倒序列表中更新i-k+1位置的值 + + res = max(res, dp[i][0], dp[i][1]) # 更新答案 return res ``` From e8cd7bd9eb6ddcda144f31f9210271591e519d68 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 19:19:33 +0800 Subject: [PATCH 15/16] Refactor getMax return statement formatting Refactor getMax method for improved readability by formatting the return statement. --- .../Solution.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java index c1cd3678fa18b..853957d6d8649 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.java @@ -51,7 +51,8 @@ private long getMax(int rangeStart, int rangeEnd, int treeIndex, int treeStart, } else if (rangeStart > mid) { return getMax(rangeStart, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd); } else { - return Math.max(getMax(rangeStart, mid, treeIndex * 2 + 1, treeStart, mid), getMax(mid + 1, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd)); + return Math.max(getMax(rangeStart, mid, treeIndex * 2 + 1, treeStart, mid), + getMax(mid + 1, rangeEnd, treeIndex * 2 + 2, mid + 1, treeEnd)); } } @@ -68,4 +69,4 @@ private void update(int rangeIndex, long value, int treeIndex, int start, int en } tree[treeIndex] = Math.max(tree[treeIndex * 2 + 1], tree[treeIndex * 2 + 2]); } -} \ No newline at end of file +} From 4060fb02e36df76444caf5818a8029266d73a068 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 13 May 2026 19:20:12 +0800 Subject: [PATCH 16/16] Refactor code formatting and improve readability --- .../Solution.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp index b3b3268ebc7be..f1448afea04ff 100644 --- a/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp +++ b/solution/3900-3999/3915.Maximum Sum of Alternating Subsequence With Distance at Least K/Solution.cpp @@ -8,24 +8,25 @@ class Solution { map mp; for (int x : nums) mp[x] = 1; int m = 0; - for (auto &p : mp) p.second = ++m; + for (auto& p : mp) p.second = ++m; for (int i = 0; i < n; i++) idx[i] = mp[nums[i]]; const long long INF = 1e18; // tree[0]:前缀最大值(用于查询 < nums[i] 的最大 f[j][0]) // tree[1]:后缀最大值(用于查询 > nums[i] 的最大 f[j][1]) long long tree[2][m + 1]; - for (int i = 0; i < 2; i++) for (int j = 0; j <= m; j++) tree[i][j] = -INF; + for (int i = 0; i < 2; i++) + for (int j = 0; j <= m; j++) tree[i][j] = -INF; // 树状数组模板开始 auto lb = [&](int x) { return x & (-x); }; - auto update = [&](long long *tree, int pos, long long val) { + auto update = [&](long long* tree, int pos, long long val) { for (; pos <= m; pos += lb(pos)) tree[pos] = max(tree[pos], val); }; - auto query = [&](long long *tree, int pos) { + auto query = [&](long long* tree, int pos) { long long ret = -INF; for (; pos; pos -= lb(pos)) ret = max(ret, tree[pos]); return ret; @@ -35,7 +36,8 @@ class Solution { long long ans = 0; long long f[n + 1][2]; - for (int i = 0; i <= n; i++) for (int j = 0; j < 2; j++) f[i][j] = -INF; + for (int i = 0; i <= n; i++) + for (int j = 0; j < 2; j++) f[i][j] = -INF; // 滑动窗口:只有 j <= i - K 的位置才加入树状数组 for (int i = 1, j = 1; i <= n; i++) { while (i - j >= K) { @@ -51,4 +53,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +};