Java 最大和子阵
我试图在一个和最大的数组中找到相邻的子数组。那么,对于数组 {5,15,30,10,5,40,10} 连续使用这些数字的最大和可能是55,或者(10+(-5)+40+10)=55。下面的程序输出55的最大和,然而,我试图解决的问题是如何打印产生55的序列。换句话说,我如何打印出10、-5、40和10Java 最大和子阵,java,arrays,algorithm,arraylist,Java,Arrays,Algorithm,Arraylist,我试图在一个和最大的数组中找到相邻的子数组。那么,对于数组 {5,15,30,10,5,40,10} 连续使用这些数字的最大和可能是55,或者(10+(-5)+40+10)=55。下面的程序输出55的最大和,然而,我试图解决的问题是如何打印产生55的序列。换句话说,我如何打印出10、-5、40和10 public static void main(String[] args) { int[] arr = {5, 15, -30, 10, -5, 40, 10}; System.
public static void main(String[] args) {
int[] arr = {5, 15, -30, 10, -5, 40, 10};
System.out.println(maxSubsequenceSum(arr));
}
public static int maxSubsequenceSum(int[] X) {
int max = X[0];
int sum = X[0];
for (int i = 1; i < X.length; i++) {
sum = Math.max(X[i], sum + X[i]);
max = Math.max(max, sum);
}
return max;
}
publicstaticvoidmain(字符串[]args){
int[]arr={5,15,-30,10,-5,40,10};
System.out.println(maxSubsequenceSum(arr));
}
公共静态int-maxSubsequenceSum(int[]X){
int max=X[0];
整数和=X[0];
对于(int i=1;i
我在考虑创建一个ArrayList来存储I的每个索引处的
sum
值,因此ArrayList看起来像(5,20,-10,10,5,45,55)。然后我计划将ArrayList从索引0清除为列表中的第一个负数,然而,这只解决了这个特定示例的问题,但是如果我更改原始的数字数组,这个解决方案将不起作用。您需要对所有可能的子数组求和。为此,您可以执行以下代码
public static int maxSubsequenceSum(int[] X) {
int max = 0;
boolean max_init = false;
int max_from=0;
int max_to=0; // this is not included
for (int i = 0; i < X.length; i++) {
for (int j = i + 1; j < X.length + 1; j++) {
int total = 0;
for (int k = i; k < j; k++) {
total += X[k];
}
if (total > max || !max_init){
max = total;
max_init = true;
max_from = i;
max_to = j;
}
}
}
for (int i=max_from;i<max_to;i++)
System.out.print(X[i]+",");
System.out.println();
return max;
}
公共静态int-maxSubsequenceSum(int[]X){
int max=0;
布尔max_init=false;
int max_from=0;
int max_to=0;//这不包括在内
对于(int i=0;i最大值| |!最大值初始值){
最大值=总数;
max_init=真;
max_from=i;
max_to=j;
}
}
}
对于(int i=max_from;i您可以用if语句替换Math.max函数,并更新最佳子数组的开始和结束索引。Pascal版本:
if X[i] > sum + X[i] then begin
sum := X[i];
start := i;
end
else
sum := sum + X[i];
if max < sum then begin
max := sum;
finish := i;
end;
如果X[i]>sum+X[i],则开始
总和:=X[i];
开始:=i;
结束
其他的
总和:=总和+X[i];
如果max
有一个o(n)解决方案,一个通过阵列的单for循环,只要当前总数低于0,就重置子序列
{5,15,30,10,5,40,10}
- 5+15=20
- 20-30=-10(重置子序列)
- 10-5+40+10=55
- 结束。55是最大子序列
编辑:要获取子序列。。。
无论何时更改max,都要更新子序列
- 当前左索引仅在u重置时更改
- 当前右索引每次迭代都会更改
- 新建最大->保存当前左右索引
您可以跟踪循环中当前最佳子数组的起始索引和结束索引。只需执行以下操作,而不是使用max()
计算sum
和max
:
int sum_start = 0, sum_end = 0, start = 0, end = 0;
// In the for loop
if (X[i] > sum + X[i]) {
sum = X[i];
sum_start = i;
sum_end = i;
} else {
++sum_end;
}
if (sum > max) {
start = sum_start;
end = sum_end;
max = sum;
}
可以通过捕获开始和结束,同时确定最大子阵列,如下所示:
代码
解决方案可从下载两个子阵列
[1,2,3]
[4,9],不包括负数
这里的最大子数组是[4,5]
所以输出是9
这是密码
public class MaxSubArray{
static void sumM(int a[], int n){
int s1 = Integer.MAX_VALUE;
int k = Integer.MAX_VALUE;
int sum = 0;
int s2 = 0;
for(int i=0;i<n;i++){
if(a[i]<s1){
if(a[i]<0){
k = Math.min(a[i],s1);
}
}
if(a[i]>k){
sum+=a[i];
}
if(a[i]<k){
if(a[i]<0){
continue;
}
s2+=a[i];
}
}
if(sum>s2){
System.out.println(sum);
}
else{
System.out.println(s2);
}
}
public static void main(String[] args){
int a[] = {1,2,3,-7,4,5};
int n = a.length;
sumM(a,n);
}
}
公共类MaxSubArray{
静态无效总和(整数a[],整数n){
int s1=整数的最大值;
int k=整数最大值;
整数和=0;
int s2=0;
对于(int i=0;i公共静态int kadane(int[]A){
int maxSoFar=0;
int maxEndingHere=0;
//遍历给定的数组
对于(int i:A){
//更新索引“i”处子数组“ending”的最大和(通过添加
//当前元素到上一个索引“i-1”结束的最大和)
maxEndingHere=maxEndingHere+i;
//如果最大和为负数,则将其设置为0(表示
//空子阵列)
maxEndingHere=Integer.max(maxEndingHere,0);
//如果发现当前子阵列和更大,则更新结果
maxSoFar=Integer.max(maxSoFar,maxEndingHere);
}
返回maxSoFar;
}
当然还有更有效的解决方案吗?这似乎有点低效。我正在尝试保持线性时间。你必须找到(N*(N+1))/2和。因为你有这个数量的可能和。在我的解决方案中,下一轮可能会使用一些总和作为优化。但是,你仍然必须有一个(N*(N+1))的循环/2圈。这是我的两个外环solution@Adem啊,我明白了。在这个解决方案中,我可以在哪里打印或存储生成max
的实际数字序列?@Adem您不需要找到所有(N*(N+1))/2和。请参阅Kadane的算法(topicstarter发布了它的实现)问题在于要求的是子序列本身,而不仅仅是它的总和。你的解决方案甚至比我的更好……我没有注意到我可以优化掉索引上一些无用的跟踪。做得好:)
Maximum sub-array for array[5, 15, -30, 10, -5, 40, 10]: SubArray [start=3, end=6, sum=55]
public class MaxSubArray{
static void sumM(int a[], int n){
int s1 = Integer.MAX_VALUE;
int k = Integer.MAX_VALUE;
int sum = 0;
int s2 = 0;
for(int i=0;i<n;i++){
if(a[i]<s1){
if(a[i]<0){
k = Math.min(a[i],s1);
}
}
if(a[i]>k){
sum+=a[i];
}
if(a[i]<k){
if(a[i]<0){
continue;
}
s2+=a[i];
}
}
if(sum>s2){
System.out.println(sum);
}
else{
System.out.println(s2);
}
}
public static void main(String[] args){
int a[] = {1,2,3,-7,4,5};
int n = a.length;
sumM(a,n);
}
}