【Leetcode】410. Split Array Largest Sum

来源:互联网 发布:惠阳区网络问政平台 编辑:程序博客网 时间:2024/05/14 06:36

题目:https://leetcode.com/problems/split-array-largest-sum/?tab=Description

题目要求是把一个数组分成m个连续的部分,让m个部分的最大值最小。每一种分法都会存在一个最大值,目的是找出所有分法的最大值中的最小值。

有两个思路。

1.第一个是dp,或者说backtracking带memo。

定义函数find(i, m),返回从i位置开始,分成m组的解。那么这个子问题就等于,min{max{A[i], find(i + 1, m - 1)},  max{A[i] + A[i + 1], find(i + 2, m - 1)} , ...... }。直接运用这个思路,那么是一个backtracking实现,时间复杂度较高,不出意外TLE。

优化点有两个,第一个是return case,当m=1时,我们需要计算从i开始的数组的和,可以事先算好。第二个就是用一个memo记录子问题。memo[i, j]表示从i开始的数组分成j组的所有最大值当中的最小值。memo[i, j]肯定需要重复计算,因此memo很有必要。

下面是这个思路的代码:

public int splitArray(int[] nums, int m) {int[][] memo = new int[nums.length][m + 1];int[] sum = new int[nums.length];sum[nums.length - 1] = nums[nums.length - 1];for(int i = nums.length - 2; i >= 0; i--){sum[i] = sum[i + 1] + nums[i];}    return findSA(nums, 0, m, sum, memo);}public int findSA(int[] nums, int start, int m, int[] sums, int[][] memo){if(m == 1) return sums[start];if(memo[start][m] > 0)return memo[start][m];int min = Integer.MAX_VALUE, sum = 0;for(int i = start; i <= nums.length - m; i++){sum += nums[i];min = Math.min(Math.max(sum, findSA(nums, i + 1, m - 1, sums, memo)), min);}memo[start][m] = min;return memo[start][m];}


另外在答案中看到了一另一个很吊的算法。使用二分查找。设max是数组中的最大值,sum是数组的和,那么答案应该在max和sum之间。

public int splitArray_b(int[] nums, int m) {int max = 0, sum = 0;for(int i = 0; i < nums.length; i++){max = Math.max(nums[i], max);sum += nums[i];}long low = max, high = sum;while(low <= high){int mid = (int) ((low + high) / 2);if(canSplit(nums, m, mid))high = mid - 1;elselow = mid + 1;}return (int) low;}private boolean canSplit(int[] nums, int m, int upper){int sum = 0, count = 1;for(int i : nums){sum += i;if(sum > upper){count++;sum = i;if(count > m)return false;}}return true;}


这个思路其实是二分类算法的一个特殊情况,一个数组,前k个具有A特征,剩余的具有B特征,让找出第一个具有B特征的元素,使用上述思路做二分,最后返回low。这个算法的细节和返回值,我在另一篇讨论二分算法的文章里面有写到。关于返回值就是带特值判断,肯定会返回low和high中的一个。假设,第一次就找到了解,那么根据算法,我们会往左,这就导致之后的肯定都往右,最后导致l = r + 1,即l出现在r右侧,返回,此时l正好指向了解。

类似的问题,有一个first bad version:https://leetcode.com/problems/first-bad-version/?tab=Description


哎。。原本写了好多结果被csdn吞了,吐槽一下

0 0
原创粉丝点击