Skip to content

Commit 2cc828b

Browse files
committed
✨feat: add 1537
1 parent 33e3923 commit 2cc828b

File tree

5 files changed

+183
-0
lines changed

5 files changed

+183
-0
lines changed

Index/前缀和.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
| [1310. 子数组异或查询](https://leetcode-cn.com/problems/xor-queries-of-a-subarray/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xor-queries-of-a-subarray/solution/gong-shui-san-xie-yi-ti-shuang-jie-shu-z-rcgu/) | 中等 | 🤩🤩🤩🤩 |
3030
| [1442. 形成两个异或相等数组的三元组数目](https://leetcode-cn.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/solution/gong-shui-san-xie-xiang-jie-shi-yong-qia-7gzm/) | 中等 | 🤩🤩🤩 |
3131
| [1480. 一维数组的动态和](https://leetcode-cn.com/problems/running-sum-of-1d-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/running-sum-of-1d-array/solution/gong-shui-san-xie-yi-wei-qian-zhui-he-mo-g8hn/) | 简单 | 🤩🤩🤩🤩🤩 |
32+
| [1537. 最大得分](https://leetcode.cn/problems/get-the-maximum-score/) | [LeetCode 题解链接](https://leetcode.cn/problems/get-the-maximum-score/solution/by-ac_oier-ht78/) | 困难 | 🤩🤩🤩🤩 |
3233
| [1588. 所有奇数长度子数组的和](https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-18jq3/) | 简单 | 🤩🤩🤩🤩🤩 |
3334
| [1738. 找出第 K 大的异或坐标值](https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value/solution/gong-shui-san-xie-xiang-jie-li-yong-er-w-ai0d/) | 中等 | 🤩🤩🤩 |
3435
| [1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?](https://leetcode-cn.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/solution/gong-shui-san-xie-qian-zhui-he-qiu-jie-c-b38y/) | 中等 | 🤩🤩🤩🤩🤩 |

Index/双指针.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
| [1221. 分割平衡字符串](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-wumnk/) | 简单 | 🤩🤩🤩🤩 |
4747
| [1332. 删除回文子序列](https://leetcode-cn.com/problems/remove-palindromic-subsequences/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-palindromic-subsequences/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-0zwn/) | 简单 | 🤩🤩🤩🤩 |
4848
| [1446. 连续字符](https://leetcode-cn.com/problems/consecutive-characters/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/consecutive-characters/solution/gong-shui-san-xie-jian-dan-shuang-zhi-zh-xtv6/) | 简单 | 🤩🤩🤩🤩🤩 |
49+
| [1537. 最大得分](https://leetcode.cn/problems/get-the-maximum-score/) | [LeetCode 题解链接](https://leetcode.cn/problems/get-the-maximum-score/solution/by-ac_oier-ht78/) | 困难 | 🤩🤩🤩🤩 |
4950
| [1610. 可见点的最大数目](https://leetcode-cn.com/problems/maximum-number-of-visible-points/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-visible-points/solution/gong-shui-san-xie-qiu-ji-jiao-ji-he-ti-b-0bid/) | 困难 | 🤩🤩🤩🤩 |
5051
| [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/solution/gong-shui-san-xie-yi-ti-shuang-jie-dan-x-elpx/) | 中等 | 🤩🤩🤩🤩 |
5152
| [1748. 唯一元素的和](https://leetcode-cn.com/problems/sum-of-unique-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-unique-elements/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-atnd/) | 简单 | 🤩🤩🤩🤩 |

Index/序列 DP.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
| [1143. 最长公共子序列](https://leetcode-cn.com/problems/longest-common-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-common-subsequence/solution/gong-shui-san-xie-zui-chang-gong-gong-zi-xq0h/) | 中等 | 🤩🤩🤩🤩 |
1818
| [1218. 最长定差子序列](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/solution/gong-shui-san-xie-jie-he-tan-xin-de-zhua-dj1k/) | 中等 | 🤩🤩🤩🤩🤩 |
1919
| [1473. 粉刷房子 III](https://leetcode-cn.com/problems/paint-house-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/paint-house-iii/solution/gong-shui-san-xie-san-wei-dong-tai-gui-h-ud7m/) | 困难 | 🤩🤩🤩🤩 |
20+
| [1537. 最大得分](https://leetcode.cn/problems/get-the-maximum-score/) | [LeetCode 题解链接](https://leetcode.cn/problems/get-the-maximum-score/solution/by-ac_oier-ht78/) | 困难 | 🤩🤩🤩🤩 |
2021
| [1713. 得到子序列的最少操作次数](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-oj7yu/) | 困难 | 🤩🤩🤩🤩🤩 |
2122
| [1751. 最多可以参加的会议数目 II](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/solution/po-su-dp-er-fen-dp-jie-fa-by-ac_oier-88du/) | 困难 | 🤩🤩🤩🤩 |
2223

Index/构造.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| [406. 根据身高重建队列](https://leetcode.cn/problems/queue-reconstruction-by-height/) | [LeetCode 题解链接](https://leetcode.cn/problems/queue-reconstruction-by-height/solution/by-ac_oier-fda2/) | 中等 | 🤩🤩🤩🤩 |
44
| [942. 增减字符串匹配](https://leetcode.cn/problems/di-string-match/) | [LeetCode 题解链接](https://leetcode.cn/problems/di-string-match/solution/by-ac_oier-pvjk/) | 简单 | 🤩🤩🤩🤩🤩 |
55
| [961. 在长度 2N 的数组中找出重复 N 次的元素](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/solution/by-ac_oier-bslq/) | 简单 | 🤩🤩🤩🤩 |
6+
| [1537. 最大得分](https://leetcode.cn/problems/get-the-maximum-score/) | [LeetCode 题解链接](https://leetcode.cn/problems/get-the-maximum-score/solution/by-ac_oier-ht78/) | 困难 | 🤩🤩🤩🤩 |
67
| [1719. 重构一棵树的方案数](https://leetcode-cn.com/problems/number-of-ways-to-reconstruct-a-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-ways-to-reconstruct-a-tree/solution/gong-shui-san-xie-gou-zao-yan-zheng-he-f-q6fc/) | 困难 | 🤩🤩 |
78
| [2028. 找出缺失的观测数据](https://leetcode-cn.com/problems/find-missing-observations/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-missing-observations/solution/by-ac_oier-x22k/) | 中等 | 🤩🤩🤩🤩🤩 |
89

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1537. 最大得分](https://leetcode.cn/problems/get-the-maximum-score/solution/by-ac_oier-ht78/)** ,难度为 **困难**
4+
5+
Tag : 「前缀和」、「构造」、「双指针」、「序列 DP」、「动态规划」
6+
7+
8+
9+
你有两个 有序 且数组内元素互不相同的数组 `nums1` 和 `nums2` 。
10+
11+
一条 合法路径 定义如下:
12+
13+
* 选择数组 `nums1` 或者 `nums2` 开始遍历(从下标 $0$ 处开始)。
14+
* 从左到右遍历当前数组。
15+
* 如果你遇到了 `nums1` 和 `nums2` 中都存在的值,那么你可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。
16+
17+
得分定义为合法路径中不同数字的和。
18+
19+
请你返回所有可能合法路径中的最大得分。
20+
21+
由于答案可能很大,请你将它对 $10^9 + 7$ 取余后返回。
22+
23+
示例 1:
24+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/08/02/sample_1_1893.png)
25+
```
26+
输入:nums1 = [2,4,5,8,10], nums2 = [4,6,8,9]
27+
28+
输出:30
29+
30+
解释:合法路径包括:
31+
[2,4,5,8,10], [2,4,5,8,9], [2,4,6,8,9], [2,4,6,8,10],(从 nums1 开始遍历)
32+
[4,6,8,9], [4,5,8,10], [4,5,8,9], [4,6,8,10] (从 nums2 开始遍历)
33+
最大得分为上图中的绿色路径 [2,4,6,8,10] 。
34+
```
35+
示例 2:
36+
```
37+
输入:nums1 = [1,3,5,7,9], nums2 = [3,5,100]
38+
39+
输出:109
40+
41+
解释:最大得分由路径 [1,3,5,100] 得到。
42+
```
43+
示例 3:
44+
```
45+
输入:nums1 = [1,2,3,4,5], nums2 = [6,7,8,9,10]
46+
47+
输出:40
48+
49+
解释:nums1 和 nums2 之间无相同数字。
50+
最大得分由路径 [6,7,8,9,10] 得到。
51+
```
52+
示例 4:
53+
```
54+
输入:nums1 = [1,4,5,8,9,11,19], nums2 = [2,3,4,11,12]
55+
56+
输出:61
57+
```
58+
59+
提示:
60+
* $1 <= nums1.length <= 10^5$
61+
* $1 <= nums2.length <= 10^5$
62+
* $1 <= nums1[i], nums2[i] <= 10^7$
63+
* `nums1` 和 `nums2` 都是严格递增的数组。
64+
65+
---
66+
67+
### 前缀和 + 构造(分段计算)
68+
69+
一个简单且正确的做法,是我们构造一种决策方案,使得能够直接计算出最大得分。
70+
71+
首先,在最佳路径中所有的公共点都必然会经过,因此我们可以将值相等的点进行合并,即看作同一个点。
72+
73+
利用两个数组均满足「单调递增」,我们可以通过 $O(n + m)$ 的复杂度统计出那些公共点,以二元组 $(i, j)$ 的形式存储到 `list` 数组(二元组含义为 $nums1[i] = nums2[j]$)。
74+
75+
对于 `list` 中的每对相邻元素(相邻公共点),假设为 $(a_i, b_i)$ 和 $(c_i, d_i)$,我们可以通过「前缀和」计算出 $nums1[a_i ... c_i]$ 以及 $nums2[b_i ... d_i]$ 的和,从而决策出在 $nums1[a_i]$(或者说是 $nums2[b_i]$,这两个是同一个点)时,我们应当走哪一段。
76+
77+
当计算完所有公共点之间的得分后,对于最佳路线的首位两端,也是结合「前缀和」做同样的逻辑处理即可。
78+
79+
代码:
80+
```Java
81+
class Solution {
82+
int MOD = (int)1e9 + 7;
83+
public int maxSum(int[] nums1, int[] nums2) {
84+
int n = nums1.length, m = nums2.length;
85+
long[] s1 = new long[n + 10], s2 = new long[m + 10];
86+
for (int i = 1; i <= n; i++) s1[i] = s1[i - 1] + nums1[i - 1];
87+
for (int i = 1; i <= m; i++) s2[i] = s2[i - 1] + nums2[i - 1];
88+
List<int[]> list = new ArrayList<>();
89+
for (int i = 0, j = 0; i < n && j < m; ) {
90+
if (nums1[i] == nums2[j]) list.add(new int[]{i, j});
91+
if (nums1[i] < nums2[j]) i++;
92+
else j++;
93+
}
94+
long ans = 0;
95+
for (int i = 0, p1 = -1, p2 = -1; i <= list.size(); i++) {
96+
int idx1 = 0, idx2 = 0;
97+
if (i < list.size()) {
98+
int[] info = list.get(i);
99+
idx1 = info[0]; idx2 = info[1];
100+
} else {
101+
idx1 = n - 1; idx2 = m - 1;
102+
}
103+
long t1 = s1[idx1 + 1] - s1[p1 + 1], t2 = s2[idx2 + 1] - s2[p2 + 1];
104+
ans += Math.max(t1, t2);
105+
p1 = idx1; p2 = idx2;
106+
}
107+
return (int)(ans % MOD);
108+
}
109+
}
110+
```
111+
* 时间复杂度:$O(n + m)$
112+
* 空间复杂度:$O(n + m)$
113+
114+
---
115+
116+
### 序列 DP
117+
118+
另外一个较为常见的做法是「序列 DP」做法。
119+
120+
定义 $f[i]$ 代表在 `nums1` 上进行移动,到达 $nums1[i]$ 的最大得分;定义 $g[j]$ 代表在 `nums2` 上进行移动,到达 $nums[j]$ 的最大得分。
121+
122+
由于两者的分析是类似的,我们以 $f[i]$ 为例进行分析即可。
123+
124+
不失一般性考虑 $f[i]$ 如何转移,假设当前处理到的是 $nums1[i]$,根据 $nums1[i]$ 是否为公共点,进行分情况讨论:
125+
126+
* $nums1[i]$ 不为公共点,此时只能由 $nums[i - 1]$ 转移而来,即有 $f[i] = f[i - 1] + nums[i]$;
127+
* $nums1[i]$ 为公共点(假设与 $nums2[j]$ 公共),此时能够从 $nums1[i - 1]$ 或 $nums2[j - 1]$ 转移而来,我们需要取 $f[i - 1]$ 和 $g[j - 1]$ 的最大值,即有 $f[i] = g[j] = \max(f[i - 1], g[j - 1]) + nums1[i]$。
128+
129+
更重要的是,我们需要确保计算 $f[i]$ 时,$g[j - 1]$ 已被计算完成。
130+
131+
由于最佳路线必然满足「单调递增」,因此我们可以使用「双指针」来对 $f[i]$ 和 $g[j]$ 同时进行转移,每次取值小的进行更新,从而确保更新过程也是单调的,即当需要计算 $f[i]$ 时,比 $nums1[i]$ 小的 $f[X]$ 和 $g[X]$ 均被转移完成。
132+
133+
代码:
134+
```Java
135+
class Solution {
136+
int MOD = (int)1e9 + 7;
137+
public int maxSum(int[] nums1, int[] nums2) {
138+
int n = nums1.length, m = nums2.length;
139+
long[] f = new long[n + 1], g = new long[m + 1];
140+
int i = 1, j = 1;
141+
while (i <= n || j <= m) {
142+
if (i <= n && j <= m) {
143+
if (nums1[i - 1] < nums2[j - 1]) {
144+
f[i] = f[i - 1] + nums1[i - 1];
145+
i++;
146+
} else if (nums2[j - 1] < nums1[i - 1]) {
147+
g[j] = g[j - 1] + nums2[j - 1];
148+
j++;
149+
} else {
150+
f[i] = g[j] = Math.max(f[i - 1], g[j - 1]) + nums1[i - 1];
151+
i++; j++;
152+
}
153+
} else if (i <= n) {
154+
f[i] = f[i - 1] + nums1[i - 1];
155+
i++;
156+
} else {
157+
g[j] = g[j - 1] + nums2[j - 1];
158+
j++;
159+
}
160+
}
161+
return (int) (Math.max(f[n], g[m]) % MOD);
162+
}
163+
}
164+
```
165+
* 时间复杂度:$O(n + m)$
166+
* 空间复杂度:$O(n + m)$
167+
168+
---
169+
170+
### 最后
171+
172+
这是我们「刷穿 LeetCode」系列文章的第 `No.1537` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
173+
174+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
175+
176+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
177+
178+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
179+

0 commit comments

Comments
 (0)