0

I wrote this code, it passed initial test cases but it shows run time error when I submitted. I am unable to understand why? Run time error:- Index -1 array out of bounds for length 8

class Solution {
public int[] duplicateZeros(int[] arr) 
{
    int n=arr.length;
    int count=0;
    for(int i=0;i<n;i++)
    {
        if(arr[i]==0)
            count=count+1;
    }
    
    int loc= n-1;
    int p=n-1+count;
    if(count==0)
        return arr;
    for(int i=n-1,j=p;i>=0;i--,j--)
    {
        if(j<=n && loc>=0)
        {
            if(arr[i]==0)
            {
                arr[loc]=0;
                arr[loc-1]=0;
                loc=loc-2;
            }
            else
            {
                arr[loc]=arr[i];
                loc=loc-1;
            }
        }
    }
    return arr;

} }

1
  • 1
    An array is fixed length - when you are shifting elements to the right are you expected to enlarge the array or do the shifted elements get dropped from the array? Please add the input for success and failure cases. Commented Aug 12, 2021 at 10:53

3 Answers 3

1

In the following code if loc is 0 and arr[i] is 0 and j <= n you enter the nested if and arr[loc-1] is arr[-1] that can give you the ArrayOutOfBoundException

// If j <= n and loc is 0 enter the first if
if (j <= n && loc >= 0) {
   // If arr[i] == 0 enter the second if
   if (arr[i] == 0) {
       arr[loc] = 0;
       arr[loc - 1] = 0;   // loc is 0 so arr[loc - 1] throw the Error
       loc = loc - 2;
   } ...
Sign up to request clarification or add additional context in comments.

Comments

0
class Solution {
    public int[] duplicateZeros(int[] arr) {
        int n = arr.length;
        int count = 0;
        /* While we are not at the end of arr and the value is 0... */
        for(; (count < n) && (arr[count] == 0); count++) {
            /* Add one to count until we are done */
        }
        
        /* If half or more of the array is 0, then we zero things and are done */
        if (count > n/2) {
            for (int i = count; i < n; i++) {
                arr[i] = 0;
            }
            return arr;
        }

        /* We have shifting work to do :'( */
        int end = n - 1;
        int loc = n - 1 - count;
        int boundary = 2 * count;
        /* Shift from loc to end while we have not copied into a space that will be 0 */
        for(; end >= boundary; end--; loc--) {
            arr[end] = arr[loc];
        }
        
        /* Put a 0 into all the spots there should be a zero, ignoreing the places there is already a 0 */
        for (int i = count; i < boundary; i++) {
            arr[i] = 0;
        }
        /* Done! */
        return arr;
    }
}

I didn't test this code... but it should be very close to what you want. I think your issue is that you overcomplicated your code and tried to wrap your steps into if{} else{} logic you didn't need to.

You also tried to do duff's loop by setting two 0's at once.

Also, you don't need to return arr - when you return to the caling function, you will have modified the original array.

Comments

0

The biggest problem is that you are trying to create the result into the same array. If there are any 0's, this won't fit.

Here is a slightly simpler solution requiring Java 8 or higher:

public static int[] duplicateZeros(int[] arr) {
    return Arrays.stream(arr)
        .flatMap(i -> i == 0 ? IntStream.of(i, i) : IntStream.of(i))
        .toArray();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.