最大子数组的求解(包括首尾相接成环)

设计思想:首先先实现一个数组最大子数组的求法,主要用到的思想是从起始开始,当加到某一个地方和为负数的时候,那么最大子数组在这个数前面或者后面(截止到a[i]和为负,那么最大子数组存在于a[0]到a[i-1]或者a[i+1]到a[n-1]),然后实现首尾连接的环的情况,可以直接定义一个二倍长度的数组,存两遍数据,在分别从b[0]到b[n-1]中寻找n个数据的最大子数组,最后返回最大的即可。

出现的问题,解决的方案:在起初实现最大子数组的求解时,需要注意因为给予的起始值为0,所以当数据全为负数的时候,应该附加条件将其判断出来,当全是负数的时候直接找出最大的数即可,同样在首尾相接成环的时候也要加上这个判断。

源代码:

package Shi;

import java.util.*;

public class Shi {
	public static int max(int a,int b){
		if(a<b)return b;
		else return a;
	}
	public static int zumax(int a[],int n){
		int M=0;
		boolean p=false;
		for(int y=0;y<n;y++){
			if(a[y]>=0){
				p=true;
				break;
			}
		}
		if(p==false){
			M=a[0];
			for(int y=0;y<n;y++){
				if(a[y]>M){
					M=a[y];
				}
			}
		}
		else{
		int i;
		int C=0;
		for(i=0;i<n;i++){
			C+=a[i];
			if(C>M){
				M=C;
			}
			if(C<0){
				C=0;
			}
		}
		}
		return M;
	}
	public static int huan(int a[],int n){
		int b[]=new int[(2*n)];
		int Max=0;
		boolean p=false;
		for(int y=0;y<n;y++){
			if(a[y]>=0){
				p=true;
				break;
			}
		}
		if(p==false){
			Max=a[0];
			for(int y=0;y<n;y++){
				if(a[y]>Max){
					Max=a[y];
				}
			}
		}
		else{
		for(int i=0;i<n;i++){
			b[i]=a[i];
			b[i+n]=a[i];
		}
		int c[]=new int[n];
		for(int i=0;i<n;i++){
			for(int y=0;y<n;y++){
				c[y]=b[i+y];
			}
			if(Max<zumax(c,n)){
				Max=zumax(c,n);
			}
		}
		}
		return Max;
	}
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		System.out.println("输入个数");
		int nn=input.nextInt();
		int aa[]=new int[nn];
		System.out.println("输入各个数字");
		for(int i=0;i<nn;i++){
			aa[i]=input.nextInt();
		}
		System.out.println("最大的子数组为"+zumax(aa,nn));
		System.out.println("首尾相接之后新的最大子数组为"+huan(aa,nn));
	}

}

结果截图:

总结:整体来说,这个题目最关键的地方就是怎么实现在时间复杂度为n的情况下实现求解数组的最大子数组(这里是当和为负数的时候,最大子数组存在这个数据的前部分或者后部分);后面实现环的情况的时候,直接定义一个二倍长度的数组即可实现。

时间: 2024-12-18 07:35:50

最大子数组的求解(包括首尾相接成环)的相关文章

返回一个整数数组中最大子数组的和,首尾相接

设计思想 遍历数组的时候将数组中第一个数变成最后一个数,这样就得到了好几个新的数组,然后输出每个数组的最大子数组的和,在比较每个输出结果,找到最大的子数组和. 代码 #include <iostream> #include<ctime> #define Num 10000 using namespace std; int DTGH_Sum(int a[],int n) { int sum = 0; int *b = (int *) malloc(n * sizeof(int));

数组中子数组之和最大值(首尾相接)

题目:求一维子数组的最大子数组之和(一维数组首尾相接)并写出子数组 人员: 陈晨:程序复查,结果测试. 王颖瑞:编写代码 思路: 1.求最大子数组之和:对于首尾相接的数组来说,如果计算子数组之和,最多把数组循环两遍,所以我们把数组的长度扩大了一倍(如果要算的数组是5位,那么数组就定义为10位,前半部分和后半部分一样),之后把这个数组进行分组(以要算的数组为5为例).第一个数到第五个数为一组,第二个数与第六个数为一组...第五个数到第九个数.分别把各组的子数组的最大值记录到另一个数组中.比较求出最

首尾相接二维数组(圆柱)--求最大子矩阵

一 题目:一个首尾相接的二维数组,其中有有正数,有负数,求它的最大子矩阵. 二 设计思路: 这道题基本无难度,因为这道题可以参考以前做过的求解二维数组的子矩阵(不是首尾相接),所以可以简单划分为两部分.第一步先将它化为一维首尾相接的数组(环),然后再利用求解环中最大子数组的思想求解.具体将二维数组化为一维数组请参考(http://www.cnblogs.com/houtaoliang/p/4401630.html),在此只简单分析求解环的最大子数组. 求解环的最大子数组可分为两种情况.第一种:当

Task 4.3 求环形数组的最大子数组和

任务要求:输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大.同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n) 1.设计思想:(假设数组长度为n.)任务要求中提出了数组可以首尾相邻,这样在求数组最大子数组和的时候就要考虑两种情况:一是最大子数组和所在数组在A[0]...A[n]之间,不包括首尾相

环形数组最大子数组的和及位置

题目: 求环形数组中最大子数组的和及位置. 实验思路: 环形数组中最大子数组的和包括两种情况 1.最大子数组和不包括连接处 设计思想见上篇 2.最大子数组和包括连接处 最大子数组的和=数组的和-最小子数组的和 程序代码: 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int Array[100]; //定义数组 6 int length; //数组长度 7 for(length=0;;) //输入数组 遇到Ent

返回一个首尾相接的二维整数数组中最大子数组的和

一.题目:返回一个二维整数数组中最大子数组的和. 二.要求: (1)输入一个二维整形数组,数组里有正数也有负数. (2)二维数组首尾相接,象个一条首尾相接带子一样. (3)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. (4)求所有子数组的和的最大值. 三.解题思路: 将两个同样的数组首尾相接合并成一个数组,在用以前求二维数组最大子数组的方法求解 四.源代码: #include<iostream> using namespace std; #include"math

首尾相接的数组(环)-最大子数组

一 题目:一个首尾相接的一维整型数组,其中有正有负,求它的最大子数组并返回它的位置. 结对开发人员:朱少辉,侯涛亮 二 设计思路:设这个数组为a[n],那么扩大数组范围,使之为a[2*n],将a[0]~a[n-1]的值赋给a[n]-a[2*n-1],那么就相当于从第i个(i=0,1,2..n-1)到第i+n(不包含i+n)个中求最大的子数组,这时可以用到求一维数组(不是环)最大子数组动态规划的思想求解,每求得一个最大值进行比较,最后可求得最大子数组.至于求位置即最大子数组下标,可以附设一个指针j

结对开发(求二维首尾相接数组的最大子数组和)

一.题目要求 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. 要求时间复杂度为O(n)题目:返回一个二维整数数组中最大子数组的和 一.设计思想 求环形二维数组最大子数组的和,可以转化为求一维数组最大子数组的和 我们有一个最初的二维数组a[n][n]找它的 最大子数组之和 1.我们先建立一个新的二维数组b[n][2*n-1], 2,这个新的二维数组就是将初始的二

首尾相接整数数组中最大子数组的和

设计思路: 可以分为两种情况:一种不跨数组第一个数的,一种是跨过第一个数的,不跨第一个数的利用上次的算法进行计算,跨数组的求首尾相接子数组和的最大值,可以考虑反面最小值的情况,然后利用总和减去最小值就是最大值的情况,最小值的求法与最大值相同. 程序源代码: #include<iostream> using namespace std; #include<vector> int main() { int i,len; int max0=0,max1=0,sum=0,min=0,sum