您的位置:首页 > 其它

Leetcode (410) Split Array Largest Sum

2016-10-24 22:37 309 查看
题目:

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

Note:

Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000.

题意:给定一个数组,不能改变数组中的数的位置,要求将数组分成m个部分,使得这m个部分的最大的和最小。

思路:虽然题目是从动态规划分类下面找的,但是注意到最小化最大值立即就想到了二分的方法去处理了。

二分处理思路:

目的是使得部分和的最大值最小,那么就可以枚举答案的值m,如果枚举出来的值能够达到,那么对于最终答案必然有 ans≤m

而实际上并不需要枚举所有m的值,因为对于值m,如果m不能满足那么大于m的值也必然不能满足,而如果m能够满足,那么必然存在小于等于m的值也满足——即二分可以解决

而要判断能不能够满足,因为数组中的数字位置不能够改变,因此只需要从头开始贪心求和,直到和大于m值时,就必然要划分多一个区间,最终要是需要的区间大于要求的,那必然不能满足(当然,如果出现某个数字比m大,也必然不能满足)

PS:二分方法的复杂度大约为O(nlog(sum))的,而因为sum一定不会超过long long,即O(64n)。而dp的方法估计为 O(n2) 评论区貌似也都是TLE的,就鸽了。。

代码:

class Solution {
private:
inline bool issatisfied(const vector<int>& nums, long long sum, int m)
{
int n = 1;
long long acc=0;
for (auto num: nums)
{
if (num > sum) return false;
acc += num;
if (acc > sum)
{
n++;
acc = num;
}
}
return n<=m && acc<=sum;
}
public:
int splitArray(vector<int>& nums, int m) {
long long right = 0;
for (auto num: nums)
{
right += num;
}

long long left=1;
while (right != left)
{
long long mid = (left+right)>>1;
if (issatisfied(nums, mid, m))
{
right=mid;
}
else
{
left=mid+1;
}
}
return left;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode