2

Problem Statement:

Given an array of n integers, find and print its number of negative subarrays on a new line.(A subarray is negative if the total sum of its elements is negative.)

Sample Input

5

1 -2 4 -5 1

Sample Output

9

Result that my code yields

Input (stdin)

5

1 -2 4 -5 1

Your Output (stdout)

7

Expected Output

9

Compiler Message

Wrong Answer

My code:

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

Where am I going wrong ?

Community
  • 1
  • 1

2 Answers2

1

Made few changes to the previous logic and now this code works fine.

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);
        }
    }
0

a solution running in O(nlogn), based idea on counting inversion

  1. calculate the prefix sum array of the given input, it contains cumulative sums
  2. count the inversion in the prefix sum array when prefix[i] > prefix[j] when i < j, also count when prefix[j] < 0

the time complexity is analyzed like merge-sort

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;
    }
}
Yossarian42
  • 1,950
  • 17
  • 14