Java 矩阵运行时错误
Java matrix runtime error
练习信:
给定一个包含 m x n 个元素(m 行,n 列)的矩阵,return 矩阵的所有元素按螺旋顺序排列。
例如,给定以下矩阵:
[
[ 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<Integer> spiralOrder(int[][] matrix) {
}
}
我的代码:
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++)
retorno.add(matrix[arriba][i]);
arriba++;
for(int i = arriba; i <= abajo; i++)
retorno.add(matrix[i][derecha]);
derecha--;
for(int i = derecha; 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]]
有什么建议吗?我真的不知道哪里出了问题。为什么会越界?
可以找到练习here
试试这个。
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<Integer> spiralOrder(int[][] matrix) {
List<Integer> 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;
}
我用这个矩阵试过你的方法:
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<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++)
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
正在向右移动。
一旦任何这两个人通过对方,你就知道他们之间没有数字,你需要立即停止循环 。这就是为什么你需要检查两个人是否互相超越 每次 有人迈出一步(在每个 for 循环之后)。
练习信:
给定一个包含 m x n 个元素(m 行,n 列)的矩阵,return 矩阵的所有元素按螺旋顺序排列。
例如,给定以下矩阵:
[
[ 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<Integer> spiralOrder(int[][] matrix) {
}
}
我的代码:
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++)
retorno.add(matrix[arriba][i]);
arriba++;
for(int i = arriba; i <= abajo; i++)
retorno.add(matrix[i][derecha]);
derecha--;
for(int i = derecha; 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]]
有什么建议吗?我真的不知道哪里出了问题。为什么会越界? 可以找到练习here
试试这个。
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<Integer> spiralOrder(int[][] matrix) {
List<Integer> 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;
}
我用这个矩阵试过你的方法:
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<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++)
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
正在向右移动。
一旦任何这两个人通过对方,你就知道他们之间没有数字,你需要立即停止循环 。这就是为什么你需要检查两个人是否互相超越 每次 有人迈出一步(在每个 for 循环之后)。