大家好,今天分享一道动态规划(Dynamic Programming)的题目,连续数列
给定一个整数数组,找出总和最大的连续数列,并返回总和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
这道题的调用:一个固定变量,两个可变变量,picked表示选过没有的状态,index表示当前的坐标.
process(int[] a,int index,boolean picked)
如果选过了,那么有几种选择
1.选当前的,继续走下一步
2.只选当前的,不继续走了,这时候返回,相当于子数组的选取停止
如果没选过,那么有几种选择
1.选当前的,走下一步
2.不选,走下一步
3.选当前的,但不继续往后看了
暴力法1
public static int maxSubArray(int[] nums) {
if(nums == null || nums.length < 1) return 0;
if(nums.length == 1) return nums[0];
return process(nums,0,false);
}
public static int process(int[] a,int index,boolean picked){
if(index >= a.length) return Integer.MIN_VALUE;
//c1++;
if(index == a.length-1) {
return Math.max(a[index],Integer.MIN_VALUE);
}
int p1 = -1,p2 = -1,p3 = -1;
if(!picked){
// 选
p1 = a[index] + process(a,index+1,true);
p2 = a[index];
// 不选
p3 = process(a,index+1,false);
}else {
p1 = a[index] + process(a,index+1,true);
p2 = a[index];
}
return Math.max(Math.max(p1,p2),p3);
}
dp的方法
因为有两个可比变量,而且第二个是一个boolean类型的,所以这里使用0代表false,1代表true,建立一个dp表,之后改。
对于无意义的值的选取,一开始笔者选的是-1,但是在[-2.-1]的例子中出错了,因为在比较时会有干扰,所以后面选择MIN_VALUE,消除了干扰
public static int maxSubArray2(int[] nums) {
if(nums == null || nums.length < 1) return 0;
if(nums.length == 1) return nums[0];
int[][] dp = new int[nums.length][2];
for (int i = 0; i < dp.length; i++) {
dp[i][0] = Integer.MIN_VALUE;
dp[i][1] = Integer.MIN_VALUE;
}
// [][0] not picked
// [][1] have picked
dp[nums.length-1][0] = nums[nums.length-1];
dp[nums.length-1][1] = nums[nums.length-1];
return process(nums,0,0,dp);
}
// picked < 0 --> not have picked
// picked > 0 --> have picked
public static int process(int[] a,int index,int picked,int[][] dp){
if(index >= a.length) return Integer.MIN_VALUE;
if(dp[index][picked] != Integer.MIN_VALUE) return dp[index][picked];
//c2++;
int p1 = Integer.MIN_VALUE,p2 = Integer.MIN_VALUE,p3 = Integer.MIN_VALUE;
if(picked == 0){
// 选
p1 = a[index] + process(a,index+1,1,dp);
p2 = a[index];
// 不选
p3 = process(a,index+1,0,dp);
dp[index][picked] = Math.max(Math.max(p1,p2),p3);
}else {
p1 = a[index] + process(a,index+1,1,dp);
p2 = a[index];
dp[index][picked] = Math.max(p1,p2);
}
return dp[index][picked];
}
欢迎点赞,评论,我们下期再见:)