您的位置:首页 > 其它

LintCode:Maximum Subarray III

2016-03-02 08:55 375 查看
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">题目:</span>


Maximum Subarray III

45:00
 Start

Given an array of integers and a number k, find k
non-overlapping
 subarrays
which have the largest sum.
The number in each subarray should be contiguous.
Return the largest sum.

Have you met this question in a real interview? 

Yes



据说这是一道hard题

这两天一直在研究最大子序列的花式变形以及follow up。等due赶完更新一篇最大子序列的总结。Max Subarray感觉还是面试的最爱啊!

这道题最合适的方法就是dp了。其实最难想的也是dp方程。仔细读题求K个不重叠的子序列的最大和。既然求K个不重叠的最大子序列之和。那么仔细想一想第K-1个最大子序列和是怎样一种情况。

K个子序列的最大 其实就是K-1个子序列的最大和加上第K-1个子序列的最后一个数到最后一个数这段数组中的最大子数组。但是问题又来了,第K-1个子数组的最后一个下标是多少呢?刚开始自己也被这个情况所困扰,但是再仔细想一想,第K-1个子数组的一个边界条件是其最后一个数刚好是第K-1个(每个子数组只有一个数并且连续)另外一个边界条件是整个数组的倒数第二个。(不是倒数第一个的原因是要给那个所求的最大子数组留出空间),既然不知道具体的位置,就把所有的可能求一遍取最值吧。所以DP方程可得:

dp[ i ][ j ] =  Max( dp[ p ][ j - 1] + MaxSubArray[ p+1 ][ i ] );     j -1 <= p <=i-1; dp[ i ][ j ]表示在前i个数中取j个子数组的值的Max;

public class Solution {
/**
* @param nums: A list of integers
* @param k: An integer denote to find k non-overlapping subarrays
* @return: An integer denote the sum of max k non-overlapping subarrays
*/
public int maxSubArray(int[] nums, int k) {
// write your code here
//Dp formula get: dp[i][j] = Max(dp[p][j-1]+MaxSub[p+1][i]) j-1<=p<=i-1
if(nums == null || nums.length == 0){
return 0;
}
if(k > nums.length){
return 0;
}

int[][]dp = new int[nums.length + 1][k + 1];
dp[0][0] = 0;
for(int i = 1; i <= nums.length;i++){
for(int j = 1; j <=k&&j <= i;j++){
int Max = Integer.MIN_VALUE;
for(int p = j-1;p <= i-1;p++){
Max = Math.max(dp[p][j-1]+MaxSub(nums,p+1,i),Max);
}
dp[i][j] = Max;
}
}
return dp[nums.length][k];
}
private int MaxSub(int[] nums,int i,int k){

int[]MaxSubHelper = new int[k-i+2];
MaxSubHelper[0] = 0;
for(int j = 1;j < MaxSubHelper.length;j++){
MaxSubHelper[j] = MaxSubHelper[j-1]+nums[i-1+j-1];
}

int Max = Integer.MIN_VALUE;
int MaxSum = 0;
int MinPrice = Integer.MAX_VALUE;

for(int m = 1; m < MaxSubHelper.length;m++){
MinPrice = Math.min(MinPrice,MaxSubHelper[m-1]);
MaxSum = MaxSubHelper[m] - MinPrice;
Max = Math.max(Max,MaxSum);
}

return Max;

}
}

如果K > 数组的长度那么就没有意义了。所以第二个循环添加了一个判断条件作为一个剪纸,防止超时(事实证明确实挺慢的- -)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: