LeetCode: Split Array Largest Sum

来源:互联网 发布:15年nba总决赛数据 编辑:程序博客网 时间:2024/05/01 20:26

题目:
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.

Examples:
Input:
nums = [7,2,5,10,8]
m = 2
Output:
18
Explanation:
There are four ways to split nums into two subarrays.
The best way is to split it into [7,2,5] and [10,8],
where the largest sum among the two subarrays is only 18.

题目给出一个数组nums和分割数m,将nums分割成m份,可以用不同的分割方法,要求找出m份数组中最大和的最小值result。

参考了网上二分法的算法:假设数组nums的长度为n,整个数组最多分成n份,此时这n份数组中的最大和即为nums数组中最大的元素,且是最小的最大和(因为只有一种分法),result=max(nums[i]);整个数组最少只分成一份,此时最小的最大和为所有元素之和(只有一种分法),result=sum(nums[i])。所以我们要求的result值应该是介于max(nums[i])和sum(nums[i])之间的,使用二分法来求result:求出当前范围内的中间元素mid,判断result值是否可能等于mid,如果可能,缩小范围,high=mid,求出更小的可行解;如果不可能,说明result是一个更大的数,low=mid+1。直到low=high。

判断result值是否可能等于mid:从前往后遍历数组,将前i个元素相加得到sum,如果sum+nums[i+1]不大于mid,将nums[i+1]加到sum中。否则,说明前i个元素必须被分成一份才能使result值不超过mid,份数加一,从i+1个元素开始继续遍历,判断遍历完后的份数是否超过m,如果超过,则说明result值不能等于mid,否则说明result值可能等于mid。

判断result值是否可能等于mid的时间复杂度为o(n),二分法的时间复杂度为o(logn),所以算法的时间复杂度为o(nlogn)。要注意Note中的提示,low,high,mid,result的值可能非常大,为了表示它们,要使用长整型变量。

Accepted的代码:

class Solution {public:    int splitArray(vector<int>& nums, int m) {        //得到最大值和最小值        long int low=nums[0],high=0;        for(int i=0;i<nums.size();i++)        {            if(nums[i]>low) low=nums[i];            high+=nums[i];        }        //二分搜索        while(low<high)        {            long int mid=(low+high)/2;            if(isTrue(nums,mid,m)) high=mid;            else low=mid+1;        }        return low;    }    //判断结果是否可能为mid    bool isTrue(vector<int>& nums,int mid,int m)    {        int count=1;//数组的分段数        int sum=0;//每小段的和        for(int i=0;i<nums.size();i++)        {            if(sum+nums[i]<=mid)            {                sum+=nums[i];            }            else             {                count++;                sum=nums[i];                if(count>m) return false;            }        }        return true;    }};
0 0
原创粉丝点击