leetcode-410. Split Array Largest Sum
来源:互联网 发布:php缓存技术有哪些 编辑:程序博客网 时间:2024/05/18 02:45
题目:
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 = 2Output:18Explanation: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.简单意思就是:给你一个含有n个元素的数组,让你把这数组划分成m段,那么每个段的所有元素就有一个sum,那么一次划分就会有一个最大的和(largest_sum),现在就是让你
求这个largest_sum的最小值!!!
方法一:
刚开始拿到这个题目,看到它的提示是动态规划,就一直想,就是想不出来后来在网上找到了大神们都用二分查找算法,但是这些博客没有对算法的思路有个详细的介绍,本文
就二分查找方法给出自己的理解!!
代码(模仿大神们的思想写的):
<pre name="code" class="cpp">class Solution {public:bool is_reach(vector<int>& arr, int m, long target_sum){long cur_sum = arr[0];int sections = 1;for (int i = 1; i < arr.size(); ++i){cur_sum += arr[i];if (cur_sum > target_sum){++sections;cur_sum = arr[i];}}if (sections > m)return false;//如果段计数器值大于m,假设题目要求m=3,而我们求得的段的大小为4,return true;}int splitArray(vector<int>& arr, int m) {int n = arr.size();long low = arr[0], high = arr[0];for (int i = 1; i < n; ++i){low = max(low, long(arr[i]));//数组的单个最大元素high += arr[i];//数组的所有元素}int res = 0;while (low < high){long mid = (low + high) / 2;if (is_reach(arr, m, mid)){high = mid;res = mid;}elselow = mid + 1;}return low;}};
Submission Result: Accepted More Details
Share your acceptance!
解析(leetcode上大神给的解释):
1.我们可以这样对待数组,我们将数组分成每段小于或等于target_num的小组,那么每个小组的和肯定小于或等于target_sum,如果此时我们得到的分段数目小于或等于m,
那么确定最大子段和小于或等于target_sum,否则,最大子段和的最小值一定大于target_sum;
2. 在设计的时候一定要注意: 如果写成high=mid和low=mid的模式,则有可能陷入死循环的可能,因为我们最后low,mid和high的指针的转态如下图所示:
如果is_reach传回的值是true,那么执行low=mid,那么会陷入死循环!!!!
方法二:
利用动态规划思想:
版本1:
int splitArray1(vector<int>nums, int m){int L = nums.size();int *S = new int[L + 1];S[0] = 0;for (int i = 0; i<L; i++)S[i + 1] = S[i] + nums[i];int *dp = new int[L];for (int i = 0; i<L; i++)dp[i] = S[L] - S[i];for (int s = 1; s<m; s++){for (int i = 0; i<L - s; i++){dp[i] = INT_MAX;for (int j = i + 1; j <= L - s; j++){int t = max(dp[j], S[j] - S[i]);if (t <= dp[i])dp[i] = t;else break;}}}int re = dp[0];delete[]S;delete[]dp;return re;}
Submission Result: Accepted More Details
版本2:
class Solution {public:int splitArray(vector<int>& nums, int m) {int size = nums.size();vector<int>row(size,0);vector<vector<int>>re;for (int i = 0; i <= m; i++)re.push_back(row);//二维数组//将数组分成1段的情况int sum = 0;for (int j = 0; j < size; j++){sum += nums[j];re[1][j] = sum;}//填表int temp, now;for (int i = 2; i <= m;i++){//i表示要分成的段数for (int j = i - 1; j < size;j++){temp = INT_MAX;for (int k = i - 2; k <= j - 1; k++){//re[i][j]表示将数组索引从0到j的元素分成i段now = max(re[i-1][k],re[1][j]-re[1][k]);if (now<=temp)temp = now;}re[i][j] = temp;}}return re[m][size - 1];}};结果:
Status:
Time Limit Exceeded
这个说明思想没有问题的,但是时间复杂度较高,运行超时,还要进一步优化!!!
算法思想:
re[s][j]:表示数组元素下标从0到j分成s段的结果;
re[s+1][j]:表示数组元素下标从0到j分成s+1段的结果,那么re[s+1][j]=min{max(d[s,k],a[k+1]+a[k+2]+....+a[j])},其中,s-2<=k<=j-1(见代码).
- 【Leetcode】410. Split Array Largest Sum
- leetcode 410.Split Array Largest Sum
- leetcode-410. Split Array Largest Sum
- 【LeetCode】410. Split Array Largest Sum
- Leetcode 410. Split Array Largest Sum
- [LeetCode]410. Split Array Largest Sum
- leetcode 410.Split Array Largest Sum(Hard)
- 【Leetcode】410. Split Array Largest Sum
- LeetCode 410. Split Array Largest Sum
- LeetCode 410. Split Array Largest Sum
- LeetCode 410. Split Array Largest Sum
- leetcode 410. Split Array Largest Sum
- [leetcode]410. Split Array Largest Sum
- Leetcode 410. Split Array Largest Sum
- Leetcode 410. Split Array Largest Sum
- LeetCode 410. Split Array Largest Sum
- leetcode 410. Split Array Largest Sum
- leetcode题解-410. Split Array Largest Sum
- opencv检测绿色物体(高8cm,宽15cm)
- 25.Native和Html5的交互(在anroid中使用html5,实现UI交互和数据显示)
- 日常心得 2016-10-20
- 超级喜欢老罗,2016发布了新手机
- React-建立实时评论应用
- leetcode-410. Split Array Largest Sum
- 【51Nod 1103】N的倍数
- 求连续子串的和的最大值
- 常见类型
- BITCS2016程序设计 | 15. 谁更机智
- 继续关注回归和最小二乘法OLS
- HDU 4421Bit Magic 2-sat判断可行解
- 校招总结
- 大功率PCB设计主要事项