Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最大和子阵_Java_Arrays_Algorithm_Arraylist - Fatal编程技术网

Java 最大和子阵

Java 最大和子阵,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.

我试图在一个和最大的数组中找到相邻的子数组。那么,对于数组

{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.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);
    }

    
}