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>
45:00
Start
Given an array of integers and a number k, find k
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 > 数组的长度那么就没有意义了。所以第二个循环添加了一个判断条件作为一个剪纸,防止超时(事实证明确实挺慢的- -)。
Maximum Subarray III
45:00Start
Given an array of integers and a number k, find k
non-overlappingsubarrays
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 > 数组的长度那么就没有意义了。所以第二个循环添加了一个判断条件作为一个剪纸,防止超时(事实证明确实挺慢的- -)。
相关文章推荐
- 取火柴
- eductional codeforces round 9 C
- 天天敲打胃经和大肠经是预防衰老的秘方
- 我的软件工程课目标2
- crontab-gui
- c++时间函数
- ExtJs:xtype的含义
- 深度学习-LeCun、Bengio和Hinton的联合综述(下)
- 九宫格图片浏览器
- js密码强度实时检测代码
- CREATE TRIGGER [dbo].[tr_delete] INSTEAD OF DELETE
- PowerDesigner Name中的字符COPY至Comment
- scrollview始终显示滚动条 Android
- android gps驱动 可见/已连接卫星支持北斗
- 数位DP入门题 hdu 2089 hdu 3555
- ext.reg干什么的
- 玫瑰的激情——补肾最强法
- ffmpeg解码流程
- kaggle实战之Titanic (1)-预处理
- centos 6.5中安装hadoop2.2