Find the index in a circular array from which prefix sum is always non-negative

• Difficulty Level : Hard
• Last Updated : 29 Apr, 2021

Given a circular array arr[] consisting of N integers, the task is to find the starting index of the circular array such that the prefix sum from that index is always non-negative. If there exists no such index, then print “-1”.

Examples:

Input: arr[] = {3, -6, 7, -1, -4, 5, -1}
Output: 2
Explanation:
Consider the index 2 from where the prefix sum of the given circular array is being calculated, then the prefix sum is given by {9, 3, 7, 6, 2, 7, 6}

Input: arr[] = {3, -5, -1}
Output: -1

Approach: The given problem can be solved based on the following observations:

Follow the steps to solve the problem:

• Initialize a variable, say sum as 0, that stores the sum of array elements.
• Initialize a variable, say in as 0 that stores the starting index for the circular traversal.
• Initialize a variable, say min as INT_MAX that stores the minimum prefix sum of the array arr[].
• Traverse the given array and perform the following steps:
• Update the value of sum as the sum of sum and the current element arr[i].
• If the value of sum is less than min, then update the min as sum and in as (i + 1).
• If the sum of the array is negative, then print -1. Otherwise, print the value of (in % N) as the resultant possible index.

Below is the implementation of the above approach:

C++

 // C++ program for the above approach #include using namespace std; // Function to find the starting index// of the given circular array s.t.// prefix sum array is non negativeint startingPoint(int A[], int N){    // Stores the sum of the array    int sum = 0;     // Stores the starting index    int in = 0;     // Stores the minimum prefix    // sum of A[0..i]    int min = INT_MAX;     // Traverse the array arr[]    for (int i = 0; i < N; i++) {         // Update the value of sum        sum += A[i];         // If sum is less than min        if (sum < min) {             // Update the min as the            // value of prefix sum            min = sum;             // Update in            in = i + 1;        }    }     // Otherwise, no such index is    // possible    if (sum < 0) {        return -1;    }     return in % N;} // Driver Codeint main(){    int arr[] = { 3, -6, 7, -4, -4, 6, -1 };    int N = (sizeof(arr) / sizeof(arr));    cout << startingPoint(arr, N);     return 0;}

Java

 // Java program for the above approachimport java.io.*;import java.lang.*;import java.util.*; class GFG{ // Function to find the starting index// of the given circular array s.t.// prefix sum array is non negativestatic int startingPoint(int A[], int N){         // Stores the sum of the array    int sum = 0;     // Stores the starting index    int in = 0;     // Stores the minimum prefix    // sum of A[0..i]    int min = Integer.MAX_VALUE;     // Traverse the array arr[]    for(int i = 0; i < N; i++)    {                 // Update the value of sum        sum += A[i];         // If sum is less than min        if (sum < min)        {             // Update the min as the            // value of prefix sum            min = sum;             // Update in            in = i + 1;        }    }     // Otherwise, no such index is    // possible    if (sum < 0)    {        return -1;    }     return in % N;} // Driver Codepublic static void main(String[] args){    int arr[] = { 3, -6, 7, -4, -4, 6, -1 };    int N = arr.length;         System.out.print(startingPoint(arr, N));}} // This code is contributed by Kingash

Python3

 # Python3 program for the above approach # Function to find the starting index# of the given circular array# prefix sum array is non negativeimport sys def startingPoint(A, N):         # Stores the sum of the array    sum = 0         # Stores the starting index    startingindex = 0         # Stores the minimum prefix    # sum of A[0..i]    min = sys.maxsize         # Traverse the array    for i in range(0, N):                 # Update the value of sum        sum += A[i]                 # If sum is less than minimum        if (sum < min):                         # Update the min as            # the value of prefix sum            min = sum                         # Update starting index            startingindex = i + 1                 # Otherwise no such index is possible    if (sum < 0):        return -1             return startingindex % N # Driver codearr = [ 3, -6, 7, -4, -4, 6, -1 ]N = len(arr) print(startingPoint(arr,N)) # This code is contributed by Virusbuddah

C#

 // C# program for the above approachusing System; class GFG{     // Function to find the starting index// of the given circular array s.t.// prefix sum array is non negativestatic int startingPoint(int[] A, int N){         // Stores the sum of the array    int sum = 0;     // Stores the starting index    int ind = 0;     // Stores the minimum prefix    // sum of A[0..i]    int min = Int32.MaxValue;     // Traverse the array arr[]    for(int i = 0; i < N; i++)    {                 // Update the value of sum        sum += A[i];         // If sum is less than min        if (sum < min)        {                         // Update the min as the            // value of prefix sum            min = sum;             // Update in            ind = i + 1;        }    }     // Otherwise, no such index is    // possible    if (sum < 0)    {        return -1;    }     return ind % N;} // Driver Codepublic static void Main(){    int[] arr = { 3, -6, 7, -4, -4, 6, -1 };    int N = arr.Length;         Console.Write(startingPoint(arr, N));}} // This code is contributed by ukasp

Javascript


Output:
5

Time Complexity: O(N)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up