giovanni ghisellini - 7 months ago 24
Java Question

# Java matrix runtime error

Exercise letter:

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example, Given the following matrix:

``````[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
``````

Given code:

``````public class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
}
}
``````

My code:

``````public List<Integer> spiralOrder(int[][] matrix) {
if(matrix == null || (matrix.length == 0))
return new ArrayList<Integer>();
int arriba = 0;
int derecha = matrix[0].length - 1;
int abajo = matrix.length - 1;
int izquierda = 0;
List<Integer> retorno = new ArrayList<Integer>();
while(true)
{
for(int i = izquierda; i <= derecha; i++)
arriba++;
for(int i = arriba; i <= abajo; i++)
derecha--;
for(int i = derecha; i >= izquierda; i--)
abajo--;
for(int i = abajo; i >= arriba; i--)
izquierda++;
if(izquierda >= derecha)
return retorno;
}
}
}
``````

The error:

``````Runtime Error Message:
Line 13: java.lang.ArrayIndexOutOfBoundsException: 1
Last executed input:
[[1,2,3,4,5,6,7,8,9,10]]
``````

Any suggestions? I can't really tell what is wrong. Why is it out of bounds?
Exercise can be found here

I tried your method with this matrix:

``````int[][] matrix = {{1,2,3},
{2,3,4},
{3,4,5}};
``````

and I did not get any `ArrayIndexOutOfBoundsException`. Your code does not seem to throw any errors.

However, I noticed that the output is not as expected. The output it gave me was `12345432` (only 8 numbers), missing the number `3` in the middle of the matrix.

After having a thorough look at your code I realised that the error lies in `if(izquierda >= derecha)`. If you change this to `if(izquierda > derecha)` it will not miss the `3`. For the same reason you did this, you need to also check for `arriba > abajo`, otherwise your program does not work for any matrix that has more columns than rows.

Edit: You need these checks after every for-loop.

I suggest you move the `return retorno;` outside the while-loop, and insert `break` in the checks:

``````public List<Integer> spiralOrder(int[][] matrix) {
if(matrix == null || (matrix.length == 0))
return new ArrayList<Integer>();
int arriba = 0;
int derecha = matrix[0].length - 1;
int abajo = matrix.length - 1;
int izquierda = 0;
List<Integer> retorno = new ArrayList<Integer>();
while(true)
{
for(int i = izquierda; i <= derecha; i++)
arriba++;
if(arriba > abajo)
break;

for(int i = arriba; i <= abajo; i++)
derecha--;
if(izquierda > derecha)
break;

for(int i = derecha; i >= izquierda; i--)
abajo--;
if(arriba > abajo)
break;

for(int i = abajo; i >= arriba; i--)
Side note: It was not easy making sense of `izquierda`, `derecha`, `arriba`, and `abajo`, since they "move around" in the spiral. But if you think of them as "marking" the non-checked sides of the matrix, you see that `izquierda` and `derecha` are both marking down the number `3`, but since you have written `>=`, you ignored it and missed the `3`.