如何从给定数组中打印负数子阵列的数量?

时间:2016-10-03 12:37:58

标签: java sub-array

问题陈述:

给定n个整数数组,在新行上查找并打印其负数子数。(如果子元素的总和为负,则子数组为负数。)

示例输入

5

1 -2 4 -5 1

示例输出

9

我的代码产生的结果

  

输入(stdin)

     

5

     

1 -2 4 -5 1

     

你的输出(标准输出)

     

7

     

预期产出

     

9

     

编译器消息

     

错误答案

我的代码:

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int a[] = new int[n];
        int b[] = new int[n];
        int count=0;
        int i,j,sum = 0;
        for(i=0;i<n;i++)
            {
            a[i] = scan.nextInt();            
        }
        for(i=0;i<n;i++)
            {
        if(a[i]<0){count++;}
        }
        for(i=0;i<n;i++)
            {
            for(j=0;j<n;j++)
                {
            sum = a[i] + sum;
            b[j] = sum;
            }
        }
        for(j=0;j<n;j++)
                {
        if(b[j]<0){count++;}
        }
        System.out.println(count);

    } 
}

我哪里错了?

2 个答案:

答案 0 :(得分:0)

对之前的逻辑进行了一些更改,现在这段代码运行正常。

import java.util.*;
public class Solution {

      public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            int n = scan.nextInt();
            int a[] = new int[n];
            int count=0;
            int i,j,sum = 0;
            for(i=0;i<n;i++)
            {
                a[i] = scan.nextInt();
            }
            scan.close();
            for(i=0;i<n;i++)
            {
                sum = 0;
                for(j=i;j<n;j++)
                {
                    sum = a[j] + sum;
                    if(sum<0){
                        count++;
                    }
                }
            }
            System.out.println(count);
        }
    }

答案 1 :(得分:0)

基于计数反转的思想在O(nlogn)中运行的解决方案

  1. 计算给定输入的前缀和数组,其中包含累加和
  2. prefix[i] > prefix[j] when i < j时计数前缀和数组中的求反,在prefix[j] < 0时也计数

时间复杂度像合并排序一样分析

import java.util.*;

public class NegativeSumSubarray {

    public static void main(String[] args) {
        int[] array = { 1, -2, 4, -5, 1 };

        int[] prefixSum = new int[array.length];
        prefixSum[0] = array[0];
        for (int i = 1; i < prefixSum.length; i++) {
            prefixSum[i] = prefixSum[i - 1] + array[i];
        }

        int count = countInversion(prefixSum, 0, prefixSum.length - 1);
        System.out.println(count); // 9
    }

    public static int countInversion(int[] prefixSum, int left, int right) {
        // merge-sort like counting inversion in prefixSum array
        if (left == right) {
            if (prefixSum[left] < 0) {
                return 1;
            }
            return 0;
        }
        int mid = (left + right) / 2;
        int count_left = countInversion(prefixSum, left, mid);
        int count_right = countInversion(prefixSum, mid + 1, right);
        int count_cross = countCrossInversion(prefixSum, left, mid, right);
        return count_left + count_right + count_cross;
    }

    public static int countCrossInversion(int[] prefixSum, int left, int mid, int right) {
        List<Integer> L = new ArrayList<>();
        for (int i = left; i <= mid; i++) {
            L.add(prefixSum[i]);
        }
        L.add(Integer.MAX_VALUE);

        List<Integer> R = new ArrayList<>();
        for (int i = mid + 1; i <= right; i++) {
            R.add(prefixSum[i]);
        }
        R.add(Integer.MAX_VALUE);

        int count = 0;
        int i = 0;
        int j = 0;
        for (int k = left; k <= right; k++) {
            if (L.get(i) <=  R.get(j)) {
                prefixSum[k] = L.get(i);
                i += 1;
            } else {
                prefixSum[k] = R.get(j);
                count += L.size() - 1 - i; // size() counts additional sentinal MAX_VALUE
                j += 1;
            }
        }
        return count;
    }
}