Skip to content

Commit 11a51d3

Browse files
authored
Merge pull request #196 from LetMeFly666/410
添加了问题“410.分割数组的最大值”的代码和题解
2 parents 3514c7f + 280f725 commit 11a51d3

File tree

4 files changed

+239
-0
lines changed

4 files changed

+239
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2024-01-21 13:16:50
4+
* @LastEditors: LetMeFly
5+
* @LastEditTime: 2024-01-21 13:26:47
6+
*/
7+
#ifdef _WIN32
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
class Solution {
12+
private:
13+
bool check(vector<int>& nums, int k, int s) {
14+
int cnt = 0;
15+
for (int t : nums) {
16+
if (t > s) {
17+
return false;
18+
}
19+
if (t + cnt > s) {
20+
k--;
21+
cnt = 0;
22+
}
23+
cnt += t;
24+
}
25+
return --k >= 0;
26+
}
27+
public:
28+
int splitArray(vector<int>& nums, int k) {
29+
int l = 0, r = accumulate(nums.begin(), nums.end(), 0) + 1;
30+
while (l < r) {
31+
int mid = (l + r) >> 1;
32+
if (check(nums, k, mid)) {
33+
r = mid;
34+
}
35+
else {
36+
l = mid + 1;
37+
}
38+
}
39+
return l;
40+
}
41+
};
42+
43+
#ifdef _WIN32
44+
/*
45+
[7,2,5,10,8] 2
46+
47+
*/
48+
int main() {
49+
string s;
50+
int t;
51+
while (cin >> s >> t) {
52+
vector<int> v = stringToVector(s);
53+
Solution sol;
54+
cout << sol.splitArray(v, t) << endl;
55+
}
56+
return 0;
57+
}
58+
#endif
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'''
2+
Author: LetMeFly
3+
Date: 2024-01-21 13:29:22
4+
LastEditors: LetMeFly
5+
LastEditTime: 2024-01-21 13:33:--
6+
'''
7+
from typing import List
8+
9+
class Solution:
10+
def check(self, k: int, s: int) -> bool:
11+
cnt = 0
12+
for t in self.nums:
13+
if t > s:
14+
return False
15+
if cnt + t > s:
16+
k -= 1
17+
cnt = 0
18+
cnt += t
19+
return k - 1 >= 0
20+
21+
def splitArray(self, nums: List[int], k: int) -> int:
22+
self.nums = nums
23+
l, r = 0, sum(nums) + 1
24+
while l < r:
25+
mid = (l + r) >> 1
26+
if self.check(k, mid):
27+
r = mid
28+
else:
29+
l = mid + 1
30+
return l

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
|0402.移掉K位数字|中等|<a href="https://leetcode.cn/problems/remove-k-digits/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2022/10/15/LeetCode%200402.%E7%A7%BB%E6%8E%89K%E4%BD%8D%E6%95%B0%E5%AD%97/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/127332829" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/remove-k-digits/solution/letmefly-402yi-diao-k-wei-shu-zi-by-tisf-6hh0/" target="_blank">LeetCode题解</a>|
159159
|0406.根据身高重建队列|中等|<a href="https://leetcode.cn/problems/queue-reconstruction-by-height/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2022/10/17/LeetCode%200406.%E6%A0%B9%E6%8D%AE%E8%BA%AB%E9%AB%98%E9%87%8D%E5%BB%BA%E9%98%9F%E5%88%97/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/127359227" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/queue-reconstruction-by-height/solution/letmefly-406gen-ju-shen-gao-zhong-jian-d-yfzu/" target="_blank">LeetCode题解</a>|
160160
|0409.最长回文串|简单|<a href="https://leetcode.cn/problems/longest-palindrome/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2022/10/17/LeetCode%200409.%E6%9C%80%E9%95%BF%E5%9B%9E%E6%96%87%E4%B8%B2/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/127359550" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/longest-palindrome/solution/letmefly-409zui-chang-hui-wen-chuan-by-t-xsid/" target="_blank">LeetCode题解</a>|
161+
|0410.分割数组的最大值|困难|<a href="https://leetcode.cn/problems/split-array-largest-sum/solutions/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2024/01/21/LeetCode%200410.%E5%88%86%E5%89%B2%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/135728821" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/split-array-largest-sum/solutions/2613456/letmefly-410fen-ge-shu-zu-de-zui-da-zhi-agh2v/" target="_blank">LeetCode题解</a>|
161162
|0415.字符串相加|简单|<a href="https://leetcode.cn/problems/add-strings/solutions/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2023/07/17/LeetCode%200415.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9B%B8%E5%8A%A0/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/131758488" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/add-strings/solutions/2346886/letmefly-415zi-fu-chuan-xiang-jia-mo-ni-r1ph3/" target="_blank">LeetCode题解</a>|
162163
|0421.数组中两个数的最大异或值|中等|<a href="https://leetcode.cn/problems/maximum-xor-of-two-numbers-in-an-array/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2022/10/19/LeetCode%200421.%E6%95%B0%E7%BB%84%E4%B8%AD%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%9A%84%E6%9C%80%E5%A4%A7%E5%BC%82%E6%88%96%E5%80%BC/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/127413219" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/maximum-xor-of-two-numbers-in-an-array/solution/letmefly-421shu-zu-zhong-liang-ge-shu-de-zaxe/" target="_blank">LeetCode题解</a>|
163164
|0445.两数相加II|中等|<a href="https://leetcode.cn/problems/add-two-numbers-ii/" target="_blank">题目地址</a>|<a href="https://blog.tisfy.eu.org/2022/10/14/LeetCode%200445.%E4%B8%A4%E6%95%B0%E7%9B%B8%E5%8A%A0II/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/127316269" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/add-two-numbers-ii/solution/letmefly-445liang-shu-xiang-jia-ii-by-ti-vbh5/" target="_blank">LeetCode题解</a>|
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
title: 410.分割数组的最大值
3+
date: 2024-01-21 13:35:04
4+
tags: [题解, LeetCode, 困难, 贪心, 数组, 二分查找, 二分, 动态规划, 前缀和]
5+
---
6+
7+
# 【LetMeFly】410.分割数组的最大值:二分
8+
9+
力扣题目链接:[https://leetcode.cn/problems/split-array-largest-sum/](https://leetcode.cn/problems/split-array-largest-sum/)
10+
11+
<p>给定一个非负整数数组 <code>nums</code> 和一个整数&nbsp;<code>m</code> ,你需要将这个数组分成&nbsp;<code>m</code><em>&nbsp;</em>个非空的连续子数组。</p>
12+
13+
<p>设计一个算法使得这&nbsp;<code>m</code><em>&nbsp;</em>个子数组各自和的最大值最小。</p>
14+
15+
<p>&nbsp;</p>
16+
17+
<p><strong>示例 1:</strong></p>
18+
19+
<pre>
20+
<strong>输入:</strong>nums = [7,2,5,10,8], m = 2
21+
<strong>输出:</strong>18
22+
<strong>解释:</strong>
23+
一共有四种方法将 nums 分割为 2 个子数组。
24+
其中最好的方式是将其分为 [7,2,5] 和 [10,8] 。
25+
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。</pre>
26+
27+
<p><strong>示例 2:</strong></p>
28+
29+
<pre>
30+
<strong>输入:</strong>nums = [1,2,3,4,5], m = 2
31+
<strong>输出:</strong>9
32+
</pre>
33+
34+
<p><strong>示例 3:</strong></p>
35+
36+
<pre>
37+
<strong>输入:</strong>nums = [1,4,4], m = 3
38+
<strong>输出:</strong>4
39+
</pre>
40+
41+
<p>&nbsp;</p>
42+
43+
<p><strong>提示:</strong></p>
44+
45+
<ul>
46+
<li><code>1 &lt;= nums.length &lt;= 1000</code></li>
47+
<li><code>0 &lt;= nums[i] &lt;= 10<sup>6</sup></code></li>
48+
<li><code>1 &lt;= m &lt;= min(50, nums.length)</code></li>
49+
</ul>
50+
51+
52+
53+
## 方法一:二分
54+
55+
写一个函数```check(s)```,返回```能否```将数组```nums```划分为```k```部分且每一部分的最大值不超过```s```
56+
57+
> 实现方法很简单,使用一个变量```cnt```来记录当前部分的元素和。
58+
>
59+
> 遍历数组,如果当前元素大于```s```,则必不可能成功划分,直接返回```false```
60+
>
61+
> ```cnt```加上当前元素超过了```s```,则将当前元素划分为一组(```k--``````cnt = 0```)。
62+
>
63+
> ```cnt```加上当前元素。
64+
>
65+
> 遍历结束后,判断```k - 1```是否大于等于```0```。若是,则返回```true```,否则返回```false```
66+
67+
有了这样的函数,我们只需要在主函数中写一个二分,枚举值```mid```是否能通过```check```
68+
69+
> ```l```初始值为```0``````r```初始值为“无穷大”(数组中所有元素之和再加一)。
70+
>
71+
> ```l < r```时,令$mid = \lfloor \frac{l+r}{2} \rfloor$。
72+
>
73+
> 如果```check(mid)```通过了,则说明```mid```为一种合法分法,尝试更小的值能否成功划分(令```r = mid```
74+
>
75+
> 否则,说明```mid```太小了,无法划分,尝试更大的值能否成功划分(令```l = mid + 1```
76+
77+
二分结束后,```l = r```,返回```l```即为答案。
78+
79+
+ 时间复杂度$O(len(nums)\times \log \sum nums)$
80+
+ 空间复杂度$O(1)$
81+
82+
### AC代码
83+
84+
#### C++
85+
86+
```cpp
87+
class Solution {
88+
private:
89+
bool check(vector<int>& nums, int k, int s) {
90+
int cnt = 0;
91+
for (int t : nums) {
92+
if (t > s) {
93+
return false;
94+
}
95+
if (t + cnt > s) {
96+
k--;
97+
cnt = 0;
98+
}
99+
cnt += t;
100+
}
101+
return --k >= 0;
102+
}
103+
public:
104+
int splitArray(vector<int>& nums, int k) {
105+
int l = 0, r = accumulate(nums.begin(), nums.end(), 0) + 1;
106+
while (l < r) {
107+
int mid = (l + r) >> 1;
108+
if (check(nums, k, mid)) {
109+
r = mid;
110+
}
111+
else {
112+
l = mid + 1;
113+
}
114+
}
115+
return l;
116+
}
117+
};
118+
```
119+
120+
#### Python
121+
122+
```python
123+
# from typing import List
124+
125+
class Solution:
126+
def check(self, k: int, s: int) -> bool:
127+
cnt = 0
128+
for t in self.nums:
129+
if t > s:
130+
return False
131+
if cnt + t > s:
132+
k -= 1
133+
cnt = 0
134+
cnt += t
135+
return k - 1 >= 0
136+
137+
def splitArray(self, nums: List[int], k: int) -> int:
138+
self.nums = nums
139+
l, r = 0, sum(nums) + 1
140+
while l < r:
141+
mid = (l + r) >> 1
142+
if self.check(k, mid):
143+
r = mid
144+
else:
145+
l = mid + 1
146+
return l
147+
```
148+
149+
> 同步发文于CSDN,原创不易,转载经作者同意后请附上[原文链接](https://blog.tisfy.eu.org/2024/01/21/LeetCode%200410.%E5%88%86%E5%89%B2%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC/)哦~
150+
> Tisfy:[https://letmefly.blog.csdn.net/article/details/135728821](https://letmefly.blog.csdn.net/article/details/135728821)

0 commit comments

Comments
 (0)