今天是leecode的第二题,随机来一道题目:最大子数组和,这道题在做完后我还举一反三多加了两个问题,加深了一下对代码的感觉。
题目感悟
1.这题让我知道了动态规划;
2.动态规划理解:它是将问题分解为更小的子问题
3.而且这道题,它并没有要你输出子数组出来,只是让你输出连续子数组的和
第一次代码
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length==0 || nums==null){
System.out.println("数组为空");
}
int currentMax=nums[0];//记录当前子数组最大和
int allMax=nums[0];//记录整个数组最大和
//对于当前元素,要么加入到子数组,要么从这个元素开始计和
//如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
for (int i = 1; i < nums.length; i++) {
currentMax=Math.max(currentMax,nums[i]+currentMax);
allMax=Math.max(currentMax,allMax);
}
return allMax;
}
}
代码报错:
报错原因
- currentMax 更新为 Math.max(9, -1 + 9) = 9,因为 nums[i] + currentMax 大于当前元素 -1。
- allMax 不变,仍为 9。
找错
问题出在这段代码上,是用当前元素和子数组和对比
currentMax=Math.max(nums[i],nums[i]+currentMax);
第二次代码:正确
class Solution2 {
public int maxSubArray(int[] nums) {
if(nums.length==0 || nums==null){
System.out.println("数组为空");
return 0;
}
int currentMax=nums[0];//记录当前子数组最大和
int allMax=nums[0];//记录整个数组最大和
//对于当前元素,要么加入到子数组,要么从这个元素开始计和
//如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
for (int i = 1; i < nums.length; i++) {
currentMax=Math.max(nums[i],nums[i]+currentMax);
allMax=Math.max(currentMax,allMax);
}
return allMax;
}
}
举一反三1:并输出连续子数组
这一次要多出start和end
package com.Nums;
class Solution {
public static int maxSubArray(int[] nums) {
if(nums.length==0 || nums==null){
System.out.println("数组为空");
}
int currentMax=nums[0];//记录当前子数组最大和
int allMax=nums[0];//记录整个数组最大和
int start=0;//起始位置
int end=0;//结束位置
//对于当前元素,要么加入到子数组,要么从这个元素开始计和
//如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
for (int i = 1; i < nums.length; i++) {
//当前元素>子数组+当前元素,从当前元素开始
if(nums[i]>nums[i]+currentMax){
currentMax=nums[i];
start=i;
}else {
//当前元素<当前元素+子数组,把它加到子数组里,变成总和
currentMax=nums[i]+currentMax;
}
//更新整个数组的总和,更新end位置
if (currentMax>allMax){
allMax=currentMax;
end=i;
}
}
System.out.print("最大子数组为:[");
for (int i = start; i <= end; i++) {
System.out.print(nums[i]+",");
}
System.out.print("]");
System.out.println();
return allMax;
}
}
举一反三2:如果不用连续子数组,求最大和
这就比较简单了,我想到了先排序,然后>0的相加即可。
class Solution {
public static int maxSubArray(int[] nums) {
if(nums.length==0 || nums==null){
System.out.println("数组为空");
}
//数组排序
Arrays.sort(nums);
if (nums.length==1 && nums[nums.length-1]<0){
return nums[nums.length-1];
}
//数组排序
Arrays.sort(nums);
System.out.println(Arrays.toString(nums));
int currentMax=nums[nums.length-1];
int allMax=nums[nums.length-1];
for (int i = nums.length-2; i >=0 ; i--) {
//只要当前元素>0,总和就加上当前元素
if(nums[i]>=0){
currentMax=nums[i]+currentMax;
allMax=currentMax;
}else {
break;
}
}
return allMax;
}
}