#java #runtime-error #dsa
Вопрос:
Я написал этот код, он прошел начальные тестовые примеры, но при отправке он показывает ошибку во время выполнения. Я не могу понять, почему? Ошибка во время выполнения:- Массив индекса -1 выходит за рамки длины 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 amp;amp; 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:
В следующем коде if loc
равно 0 и arr[i]
равно 0, и j <= n
вы вводите вложенные if и arr[loc-1]
is arr[-1]
, которые могут дать вам ArrayOutOfBoundException
// If j <= n and loc is 0 enter the first if
if (j <= n amp;amp; 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;
} ...
Ответ №2:
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) amp;amp; (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;
}
}
Я не проверял этот код… но это должно быть очень близко к тому, что вы хотите.
Я думаю, ваша проблема в том, что вы слишком усложнили свой код и попытались обернуть свои шаги в логику if{} else {}, в которой вам не было необходимости.
Вы также пытались выполнить цикл даффа, установив два 0 одновременно.
Кроме того, вам не нужно возвращать arr — когда вы вернетесь к функции caling, вы измените исходный массив.
Ответ №3:
Самая большая проблема заключается в том, что вы пытаетесь создать результат в том же массиве. Если есть какие-то 0, это не подойдет.
Вот немного более простое решение, требующее Java 8 или выше:
public static int[] duplicateZeros(int[] arr) {
return Arrays.stream(arr)
.flatMap(i -> i == 0 ? IntStream.of(i, i) : IntStream.of(i))
.toArray();
}