Skip to content

Commit 549c606

Browse files
author
lucifer
committed
feat: $1043
1 parent 1e2e936 commit 549c606

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
323323
- [1020. 飞地的数量](./problems/1020.number-of-enclaves.md)
324324
- [1023. 驼峰式匹配](./problems/1023.camelcase-matching.md)
325325
- [1031. 两个非重叠子数组的最大和](./problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md)
326+
- [1043. 分隔数组以得到最大和](./problems/1043.partition-array-for-maximum-sum.md) 🆕
326327
- [1104. 二叉树寻路](./problems/1104.path-in-zigzag-labelled-binary-tree.md)
327328
- [1131.绝对值表达式的最大值](./problems/1131.maximum-of-absolute-value-expression.md)
328329
- [1186. 删除一次得到子数组最大和](./problems/1186.maximum-subarray-sum-with-one-deletion.md)

Diff for: SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
- [1020. 飞地的数量](./problems/1020.number-of-enclaves.md)
214214
- [1023. 驼峰式匹配](./problems/1023.camelcase-matching.md)
215215
- [1031. 两个非重叠子数组的最大和](./problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md)
216+
- [1043. 分隔数组以得到最大和](./problems/1043.partition-array-for-maximum-sum.md) 🆕
216217
- [1104. 二叉树寻路](./problems/1104.path-in-zigzag-labelled-binary-tree.md)
217218
- [1131.绝对值表达式的最大值](./problems/1131.maximum-of-absolute-value-expression.md)
218219
- [1186. 删除一次得到子数组最大和](./problems/1186.maximum-subarray-sum-with-one-deletion.md)

Diff for: problems/1043.partition-array-for-maximum-sum.md

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
## 题目地址(1043. 分隔数组以得到最大和)
2+
3+
https://leetcode-cn.com/problems/partition-array-for-maximum-sum/
4+
5+
## 题目描述
6+
7+
```
8+
给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。
9+
10+
返回将数组分隔变换后能够得到的元素最大和。
11+
12+
 
13+
14+
注意,原数组和分隔后的数组对应顺序应当一致,也就是说,你只能选择分隔数组的位置而不能调整数组中的顺序。
15+
16+
 
17+
18+
示例 1:
19+
20+
输入:arr = [1,15,7,9,2,5,10], k = 3
21+
输出:84
22+
解释:
23+
因为 k=3 可以分隔成 [1,15,7] [9] [2,5,10],结果为 [15,15,15,9,10,10,10],和为 84,是该数组所有分隔变换后元素总和最大的。
24+
若是分隔成 [1] [15,7,9] [2,5,10],结果就是 [1, 15, 15, 15, 10, 10, 10] 但这种分隔方式的元素总和(76)小于上一种。
25+
26+
示例 2:
27+
28+
输入:arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
29+
输出:83
30+
31+
32+
示例 3:
33+
34+
输入:arr = [1], k = 1
35+
输出:1
36+
37+
38+
 
39+
40+
提示:
41+
42+
1 <= arr.length <= 500
43+
0 <= arr[i] <= 109
44+
1 <= k <= arr.length
45+
```
46+
47+
## 前置知识
48+
49+
- 动态规划
50+
- 记忆化递归
51+
52+
## 公司
53+
54+
- 暂无
55+
56+
## 记忆化递归
57+
58+
### 思路
59+
60+
这道题的思路无非就是暴力枚举所有的可能,求所有可能中的最大值即可。
61+
62+
因此我们可以枚举所有的 i,然后计算区间 [i:j] 的可能区间和,其中 j 的取值范围是 [i:i+k]。如何对区间求和呢? 其实也容易,只需要用一个变量 max_ele 记录区间最大值(这在遍历的时候可以同时取得),然后 max_ele \* (j-i+1) 即可,其中 j - i + 1 为区间的长度。这样我们就算出了区间 [i:i+k] 的区间和最大值。也就是说我们将问题规模缩小了,继续使用同样的方法直到问题缩小到寻常即可。使用递归可以轻松达到这一点。
63+
64+
### 代码
65+
66+
- 语言支持:Python3
67+
68+
Python3 Code:
69+
70+
```python
71+
72+
class Solution:
73+
def maxSumAfterPartitioning(self, arr: List[int], k: int) -> int:
74+
@lru_cache(None)
75+
def dp(i):
76+
if i >= len(arr): return 0
77+
ans = 0
78+
max_value = -1
79+
for steps in range(1, k + 1):
80+
if i + steps - 1 < len(arr): max_value = max(max_value, arr[i + steps - 1])
81+
else: break
82+
ans = max(ans, max_value * steps + dp(i + steps))
83+
return ans
84+
return dp(0)
85+
86+
```
87+
88+
**复杂度分析**
89+
90+
令 n 为数组长度。
91+
92+
- 时间复杂度:$O(n^2)$
93+
- 空间复杂度:$O(n)$
94+
95+
## 记忆化递归
96+
97+
### 思路
98+
99+
同上。我们可以将上面的代码改成普通 dp 形式。
100+
101+
只要:
102+
103+
- 将递归的代码改成 for 循环
104+
- 记忆化的地方用 dp 数组代替
105+
106+
即可轻松实现。
107+
108+
### 代码
109+
110+
- 语言支持:Python3
111+
112+
Python3 Code:
113+
114+
```python
115+
116+
class Solution:
117+
def maxSumAfterPartitioning(self, nums: List[int], k: int) -> int:
118+
n = len(nums)
119+
dp = [0] * (n+1)
120+
121+
for i in range(1, n+1):
122+
max_ele = 0
123+
for j in range(i, min(n+1, i+k)):
124+
max_ele = max(max_ele, nums[j-1])
125+
# range: [i,j]
126+
dp[j] = max(dp[j], (j-i+1) * max_ele + dp[i-1])
127+
return max(dp)
128+
129+
```
130+
131+
**复杂度分析**
132+
133+
令 n 为数组长度。
134+
135+
- 时间复杂度:$O(n^2)$
136+
- 空间复杂度:$O(n)$
137+
138+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
139+
140+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
141+
142+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
143+
144+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
145+
146+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)

0 commit comments

Comments
 (0)