Java矩阵运行时错误
练习信:
给定mxn元素矩阵(m行,n列),以螺旋顺序返回矩阵的所有元素。
例如,给定以下矩阵:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] You should return [1,2,3,6,9,8,7,4,5].
给定代码:
public class Solution { public List spiralOrder(int[][] matrix) { } }
我的代码:
public List spiralOrder(int[][] matrix) { if(matrix == null || (matrix.length == 0)) return new ArrayList(); int arriba = 0; int derecha = matrix[0].length - 1; int abajo = matrix.length - 1; int izquierda = 0; List retorno = new ArrayList(); while(true) { for(int i = izquierda; i <= derecha; i++) retorno.add(matrix[arriba][i]); arriba++; for(int i = arriba; i = izquierda; i--) retorno.add(matrix[abajo][i]); abajo--; for(int i = abajo; i >= arriba; i--) retorno.add(matrix[i][izquierda]); izquierda++; if(izquierda >= derecha) return retorno; } } }
错误:
Runtime Error Message: Line 13: java.lang.ArrayIndexOutOfBoundsException: 1 Last executed input: [[1,2,3,4,5,6,7,8,9,10]]
有什么建议么? 我真的不知道出了什么问题。 为什么它超出范围? 练习可以在这里找到
我用这个矩阵尝试了你的方法:
int[][] matrix = {{1,2,3}, {2,3,4}, {3,4,5}};
我没有得到任何ArrayIndexOutOfBoundsException
。 您的代码似乎没有任何错误。
但是,我注意到输出不是预期的。 它给我的输出是12345432
(只有8个数字),缺少矩阵中间的数字3
。
仔细查看代码后,我意识到错误在于if(izquierda >= derecha)
。 如果你把它if(izquierda > derecha)
它就不会错过3
。 出于同样的原因,您还需要检查arriba > abajo
,否则您的程序不适用于任何列数多于行的矩阵。
编辑:每次for循环后都需要进行这些检查。
我建议你移动return retorno;
在while循环之外,并在检查中插入break
:
public List spiralOrder(int[][] matrix) { if(matrix == null || (matrix.length == 0)) return new ArrayList (); int arriba = 0; int derecha = matrix[0].length - 1; int abajo = matrix.length - 1; int izquierda = 0; List retorno = new ArrayList (); while(true) { for(int i = izquierda; i <= derecha; i++) retorno.add(matrix[arriba][i]); arriba++; if(arriba > abajo) break; for(int i = arriba; i <= abajo; i++) retorno.add(matrix[i][derecha]); derecha--; if(izquierda > derecha) break; for(int i = derecha; i >= izquierda; i--) retorno.add(matrix[abajo][i]); abajo--; if(arriba > abajo) break; for(int i = abajo; i >= arriba; i--) retorno.add(matrix[i][izquierda]); izquierda++; if(izquierda > derecha) break; } return retorno; }
您的代码说明(按要求):想象一下,您有一个矩阵,周围有四个人 – 每个人都站在一边。 这四个人被称为arriba
, derecha
, abajo
和izquierda
:
arriba 1 2 3 4 5 izquierda 2 3 4 5 6 derecha 3 4 5 6 7 abajo
这四个人可以在他们面前看到数字线:
-
arriba
看到1 2 3 4 5
。 -
derecha
见5 6 7
。 -
abajo
看到3 4 5 6 7
。 -
izquierda
看到1 2 3
。
只要这些人员面前的所有数字都被添加到列表retorno
,他们就会向前跳一步。 例如,在第一个for循环之后,它看起来像这样:
1 2 3 4 5 arriba izquierda 2 3 4 5 6 derecha 3 4 5 6 7 abajo
在while循环的第一次迭代之后,它们就像这样:
1 2 3 4 5 arriba 2 izquierda 3 4 5 derecha 6 abajo 3 4 5 6 7
-
arriba
正在向下移动。 -
derecha
向左移动。 -
abajo
正在向上移动。 -
izquierda
正在向右移动。
一旦这两个人中的任何一个相互通过,你知道它们之间没有数字,你需要立即停止循环。 这就是为什么每次有人采取步骤(每次循环之后)都需要检查两个人是否相互通过的原因。
尝试这个。
static int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; static boolean movable(int r, int c, int height, int width, boolean[][] visited) { if (r < 0 || r >= height || c < 0 || c >= width) return false; return !visited[r][c]; } public List spiralOrder(int[][] matrix) { List result = new ArrayList<>(); int height = matrix.length; if (height == 0) return result; int width = matrix[0].length; if (width == 0) return result; boolean[][] visited = new boolean[height][width]; int direction = 0; int r = 0, c = 0; for (int i = 0; i < width * height; ++i) { result.add(matrix[r][c]); visited[r][c] = true; int[] directions = DIRECTIONS[direction % DIRECTIONS.length]; if (!movable(r + directions[0], c + directions[1], height, width, visited)) directions = DIRECTIONS[++direction % DIRECTIONS.length]; r += directions[0]; c += directions[1]; } return result; }