您的位置:首页 > 其它

leetcode 410 split-array-largest-sum

2018-02-01 12:13 423 查看

leetcode 410 split-array-largest-sum

1、题目描述:

给出一个数组,例如: [7,2,5,10,8],在给出一个整数m = 2,将这个数组切成m个非空连续的小数组,写出一个算法使得
其中各个小数组的和的最大值尽可能的小。


题目链接:https://leetcode.com/problems/split-array-largest-sum/description/

2、题目思路描述:

这个题是一道hard难度的题,如上述例子:
nums = [7,2,5,10,8]
m = 2
数组可以分为两部分,[7,2,5] [10,8] 这个数组分割后最大的和为18。
我们可以利用二分的思想来搜索这个尽可能小的数组和。二分搜索可以说是一个猜答案的过程。
数组的最大和就是整个数组的和,最小值为0,在这个区间内我们进行搜索。

我们可以把每个小数组想象成一个篮子,这样就有m个篮子,数组的每个元素都为一个权重为nums[i]的物品,
二分搜索的目的就是在区间[0,sum(nums)]内找到最小的篮子的容量,且m个篮子需装下所有的物品。


3、题目代码描述:

GitHub源码地址:
https://github.com/distanceNing/leetcode/blob/master/array/410_split_array.cpp
以下为代码实现:

class Solution {
public:
bool guess(vector<int>& nums,int m,long mid){
long sum = 0;
//每个篮子的容量是mid,
for(auto&i : nums){
if(sum + i > mid){
//当一个篮子里面装不下的时候,篮子数减少一个
--m;
//把当前这个物品装入一个新的篮子中
sum = i;
//当篮子数小于0的时候,说明每个篮子mid的容量不够用
//当某个物品的权重大于篮子的容量时,说明这个篮子装不下这个物品
if( m < 0 || i > mid)
return false;
}else
//尽可能的往这个篮子里面装东西
sum += i;
}
return m >= 1;
}

int splitArray(vector<int>& nums, int m) {
long start = 1,end = 0;
for(auto& i : nums)
end += i;
long ans = 0;
// 1 15 8 9 15
//下面这个是一个典型的二分搜索的模板
while(start <= end){
int mid = start + (end-start)/2;
//由于这个题是一个负相关的题目,数组的和和m的大小成反比,可以划分的小数组的个数m越大,那么
//这个题的解小数组的最大和也就可以越小。即篮子数越多,每个篮子里面装的物品权重越小。
//当mid的容量可以装下时,我们减小搜索区间为[start,mid-1],
if(guess(nums,m,mid)){
//mid为一个潜在的解,我们记录下它
ans = mid;
end = mid - 1;
//start = mid + 1; 正相关
}else {
//end = mid - 1;
start = mid + 1;
}
}
return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 算法