第二周课堂小测:判断数组的最大子数组
一、一维单方向数组
1、问题描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
2、思路:
1、分析可知,数组中的第一个数,是以自己为一个元素的子数组,从第二个数据开始往后每一个数有两种去路:
1)隶属于之前的子数组(即,当之前的子数组之和加上这个数之后,大与当前数)。
2)自己新创一个子数组(即,当之前的子数组之和加上这个数之后,小与当前数)。
2、遍历一遍数组,将所有可能是最大子数组的子数组的和存在相应子数组的最后一个位置。
3、遍历得出最大的子数组之和。
思路借鉴:https://www.cnblogs.com/20183544-wangzhengshuai/p/12363574.html
3、代码实现:
public class Test01 { public static void main(String[] args) { int a[] = {10,-1,4,-6,5,4,0,5,-8,-5}; int max = a[0]; for (int i = 1; i < a.length; i++) { if(a[i]+a[i-1]>a[i]) a[i] += a[i-1];//比较大小,存入当前位置 } for (int i = 1; i < a.length; i++) { if(max<a[i]) max = a[i]; } System.out.println(max); } }
4、测试结果:
二、一维循环数组
1、问题描述:
将第一个问题的数组首尾相接,求最大子数组。
2、思路:
我的设计思路比较简单粗暴,循环数组,即根据数组的个数n循环n次,每次的起始点为数组的每个元素,每次执行上个案例的操作,虽然通俗易懂,但代码晦涩,难以纠错,直到现在才算测试成功,以后一定要再继续思考,想出别的更高效的实现方案。
3、代码实现:
public class Test { public static void main(String[] args) { int a[] = {10,-1,4,-6,5,4,0,5,8,-5}; int b[][] = new int[a.length][a.length]; int x,y;//临时坐标 for (int i = 0; i < a.length; i++) { for (int j = 0; j < a.length; j++) { b[i][j] =a[j]; } } System.out.println("----before---"); for (int i = 0; i < a.length; i++) { for (int j = 0; j < a.length; j++) { System.out.print(b[i][j]+" "); } System.out.println(); } int sum = 0; for(int i=0;i<a.length;i++) { for (int j = i+1; j < i+a.length; j++) { x=(j>=a.length?j-a.length:j); y=(j-1>=a.length?j-1-a.length:j-1); if (b[i][x]+b[i][y]>b[i][x]) b[i][x] = b[i][x]+b[i][y]; sum = b[i][x]; } } int max = 0,temp; for(int j =0;j<a.length;j++) { for (int i = 1; i < a.length; i++) { if(b[j][i]>b[j][i-1]){ temp = b[j][i]; } else{ temp = b[j][i-1]; } if(max<temp) max = temp; } } System.out.println("----after---"); for (int i = 0; i < a.length; i++) { for (int j = 0; j < a.length; j++) { System.out.print(b[i][j]+" "); } System.out.println(); } System.out.println("max="+max); } }
4、测试结果:
三、感受
回头看来,代码实现真的不难,但自己就是在规定的上课时间没有完成,总结下来,还是自己太菜。假期的松懈已经让自己失去了太多。这次打击过后,以后一定会努力起来,争取按时完成任务。