leetcode 54. Matriz espiral
Dada una matriz de m
filas y columnas , devuelva todos los elementos de la matriz en orden espiral en el sentido de las agujas del reloj.n
matrix
Similar a la pregunta 29 de la Oficina de Jianzhi;
Idea: dado que estamos atravesando un círculo en el sentido de las agujas del reloj, lo recorreremos desde arriba, derecha, abajo e izquierda respectivamente. Después de completar un círculo, atravesaremos el siguiente círculo hasta que se cumpla la condición de terminación y el bucle se detenga. Durante Durante el proceso, atravesaremos el valor, lo almacenaremos en la colección y lo devolveremos a la colección;
La idea general es la que se muestra arriba, que es muy simple, pero la dificultad de esta pregunta es:
1. Asegúrese de que el valor del límite sea correcto y que no haya ninguna matriz fuera de los límites.
2. Necesitamos mantener uniforme el cierre izquierdo, la apertura derecha o la apertura izquierda y el cierre derecho durante cada recorrido.
3. Juicio de las condiciones de terminación, ¿cuándo se completa todo el recorrido?
En primer lugar, necesitamos definir cuatro variables, a saber, superior, derecha, inferior e izquierda. Representan respectivamente las posiciones de los lados superior, derecho, inferior e izquierdo del círculo actual que se está atravesando. Cada vez que se atraviesa, el correspondiente La posición se reducirá (aquí puede Para lograr apertura a la izquierda y cierre a la derecha o cierre a la izquierda y apertura a la derecha), hasta que nos encontremos con la izquierda y la derecha, o hacia arriba y hacia abajo, esto significa que cada número ha sido atravesado, que es la condición de terminación.
En resumen, el código es el siguiente:
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> lists = new ArrayList<>();
int m = matrix.length ;//定义行数
int n = matrix[0].length ;//定义列数
//上下左右
//注意,这里的上下左右四个值,分别指的是遍历这一行或者这一列时,保持不动的那个行数或列数
//例如我们遍历第一行时,行数是up保持不变,列数是i进行递增
int up = 0;//遍历时的点坐标[up,i]
int right = n-1;//[i,right]
int down = m-1;//[down,i]
int left = 0;//[i,left]
while (true){
//从左到右
for (int i = left; i <= right; i++) {lists.add(matrix[up][i]);}
if (++up>down){break;}//每一行或者一列遍历完后,都要缩圈,这里是上边向下缩圈
//up已经完成加1操作,向下移动了一行,因为下面的从上到下遍历,是从up这一行开始的
//所以就实现了我们的右闭,后面的以此类推;
//当移动后的up与down冲突时,意味着遍历已经结束了,break跳出循环,下面的同理。
//从上到下
for (int i = up; i <= down; i++) {lists.add(matrix[i][right]);}
if (--right<left){break;}//右边遍历完,向左缩圈
//从右到左
for (int i = right; i >= left; i--) {lists.add(matrix[down][i]);}
if (--down<up){break;}//下边遍历完,向上缩圈
//从下到上
for (int i = down; i >= up; i--) {lists.add(matrix[i][left]);}
if (++left>right){break;}//左边遍历完,向右缩圈
}
return lists;
}