-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProblem_0410_splitArray.cc
84 lines (78 loc) · 1.54 KB
/
Problem_0410_splitArray.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <cstdint>
#include <vector>
#include "UnitTest.h"
using namespace std;
class Solution
{
public:
// 经典二分法
// 时间复杂度O(n * log(sum)),额外空间复杂度O(1)
int splitArray(vector<int>& nums, int k)
{
long sum = 0;
for (int num : nums)
{
sum += num;
}
long ans = 0;
// 当子数组个自和最大值m变大时,被分割的parts要么不变,要么变小,符合单调性
//[0, sum] 二分
for (long l = 0, r = sum, m, need; l <= r;)
{
// 中点m
m = (r - l) / 2 + l;
// 必须让数组每一部分的累加和 <= m,请问划分成几个部分才够!
need = f(nums, m);
if (need <= k)
{
// 达标
ans = m;
r = m - 1;
}
else
{
l = m + 1;
}
}
return ans;
}
// 必须让数组arr每一部分的累加和 <= limit,请问划分成几个部分才够!
// 返回需要的部分数量
int f(vector<int>& arr, long limit)
{
int parts = 1;
int sum = 0;
for (int num : arr)
{
if (num > limit)
{
// 不存在这个方法
return INT32_MAX;
}
if (sum + num > limit)
{
parts++;
sum = num;
}
else
{
sum += num;
}
}
return parts;
}
};
void test()
{
Solution s;
vector<int> n1 = {7, 2, 5, 10, 8};
vector<int> n2 = {1, 2, 3, 4, 5};
EXPECT_EQ_INT(18, s.splitArray(n1, 2));
EXPECT_EQ_INT(9, s.splitArray(n2, 2));
EXPECT_SUMMARY;
}
int main()
{
test();
return 0;
}