最近刷leetcode碰见了最大子序列和的最大值得问题,结合自己想对dp有点了解,于是自己写了几种方法,逐步优化算法,一直达到自己认为的最优解,如果代码有失误,或者大佬们有更好的思路,可以共同探讨。
1.利用三层循环来做(暴力破解)
package Solution;
public class test3 {
//实现最大连续子数组的求和,时间复杂度为(o(n^3)),空间复杂度o(n)
static int mi,mj;
public static void maxSum(int[] arr) {
int max=arr[0];
for(int i=1;imax) {
max=sum;
mi=i-1;
mj=j-1;
}
}
}
System.out.println("最大连续数组的和为:"+max);
}
public static void main(String[] args) {
int[] arr= {3,-2,5,8,-4,-1,4};
maxSum(arr);
System.out.println("起始下标为:"+mi+" "+"终止下标为:"+mj);
}
}
2.利用两层循环+一个数组来解决
package Solution;
public class test4 {
static int mi,mj;
//实现最大连续子数组的求和,时间复杂度为(o(n^2)+o(n)),空间复杂度o(2n)
public static void maxSum(int[] arr,int[] sun) {
for(int i=1;imax) {
max=num;
mi=i-1;
mj=j-1;
}
}
}
System.out.println("最大连续子数组的和:"+max);
}
public static void main(String[] args) {
int[] arr= {3,-2,-5,8,-4,-1,4,9,-1};
int[] sun=new int[arr.length+1];
maxSum(arr,sun);
System.out.println("起始下标为:"+mi+" "+"终止下标为:"+mj);
}
}
3.利用分治思想解决
package Solution;
/**
* 用分治实现最大连续子序列求和
* @author quanhangbo
*
*/
public class test5 {
static int maxL,maxR;
//此处的x,y表示的是左开右闭的区间
public static int maxSum(int[] arr,int x,int y) {
int mid=(x+y)/2;
if(y-x==1)return arr[x];
//递归着求解左边的最大值
maxL=maxSum(arr,x,mid);
//递归着求解右边的最大值
maxR=maxSum(arr,mid,y);
//求解跨区域的左半部分的最大值
int maxLeftSum,leftSum;
maxLeftSum=leftSum=0;
for(int i=mid-1;i>=0;i--) {
leftSum+=arr[i];
if(leftSum>maxLeftSum) {
maxLeftSum=leftSum;
}
}
//求解跨区域的右半部分的最大值
int maxRightSum,rightSum;
maxRightSum=rightSum=0;
for(int i=mid;imaxRightSum) {
maxRightSum=rightSum;
}
}
//比较左边的最大值,和右边的最大值和跨区域的最大值
return Math.max(Math.max(maxL,maxR),maxLeftSum+maxRightSum);
}
public static void main(String[] args) {
int[] arr= {3,-2,-5,8,-4,-1,4,9,-1};
System.out.println(maxSum(arr,0,arr.length));
}
}
4.利用动态规划解决
package Solution;
import java.util.Arrays;
/**
* 最大连续子序列求和
* @author quanhangbo
*
*/
public class test11 {
public static void main(String[] args) {
int[] arr=new int[] {-2,-1};
int i,x=arr[0];
//遍历数组,其中arr[i]表示的是连续子数组中当前的最大和值(只有两个选择,要么加,要么不加,比较这两种情况求最大值)
for(i=1;i
5.递推解决(至今感觉最优的解法了)时间复杂度o(n),空间复杂度o(1)
package Solution;
public class test12 {
public static void main(String[] args) {
int[] arr=new int[] {-2,1,-3,4,-1,2,1,-5,4};
int arrsum=arr[0],sum=0;
for(int i=0;iarrsum) {
arrsum=sum;
}
if(sum<0) {
sum=0;
}
}
System.out.println(arrsum);
}
}
这是最后一个代码在leetcode中的运行结果。