Matriz espiral (atraviesa la matriz en el sentido de las agujas del reloj)

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.nmatrix

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

Supongo que te gusta

Origin blog.csdn.net/weixin_52394141/article/details/131310335
Recomendado
Clasificación