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; } 

您的代码说明(按要求):想象一下,您有一个矩阵,周围有四个人 – 每个人都站在一边。 这四个人被称为arribaderechaabajoizquierda

  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
  • derecha5 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; }