matriz rotativa leetcode189

Prefacio

2019.10.27 check-in

El algoritmo es el método para resolver el problema. El mismo problema, utilizando diferentes algoritmos, aunque los resultados obtenidos son los mismos, pero el tiempo y los recursos consumidos son diferentes. Esto requiere que aprendamos algoritmos y descubramos qué algoritmo es mejor.

tema

Un leetcode189 todos los días. Matriz giratoria

Categoría: Array

Dificultad: fácil

Enlace de título: https://leetcode-cn.com/problems/rotate-array/

Descripción del Título

Dada una matriz, mueva los elementos de la matriz k posiciones a la derecha, donde k es un número no negativo.

Ejemplo 1:

Entrada: [1,2,3,4,5,6,7] yk = 3
Salida: [5,6,7,1,2,3,4]
Explicación:
Girar a la derecha 1 paso: [7,1 , 2,3,4,5,6]
Girar a la derecha 2 pasos: [6,7,1,2,3,4,5]
Girar a la derecha 3 pasos: [5,6,7,1,2,3 , 4]

Ejemplo 2:

Entrada: [-1, -100,3,99] yk = 2
Salida: [3,99, -1, -100]
Explicación:
rotación a la derecha Paso 1: [99, -1, -100,3]
a Girar a la derecha 2 pasos: [3,99, -1, -100]

Descripción:

  • Piense en tantas soluciones como sea posible Hay al menos tres formas diferentes de resolver este problema.
  • Es necesario utilizar un algoritmo in situ con una complejidad espacial de O (1).

responder

hazlo tu mismo

  • Ideas

Soy demasiado inteligente, siento que moverme en un lugar es tan complicado que tengo que usar memoria extra para lograrlo. Eso es para poner la matriz en la lista, porque la lista puede operar en la cabeza y la cola, porque cada vez que te mueves un bit hacia la derecha, puedes eliminar de la cola e insertar el elemento eliminado en la cabeza.

  • Código
class Solution {
    public void rotate(int[] nums, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0; i<nums.length; i  ){
            list.add(nums[i]);
        }
        for(int i = 0; i < k; i  ) {
            int target = list.remove(nums.length-1);
            list.add(0,target);
        }
        int[] array = new int[]{};
        for (int i =0;i<list.size();i  ) {
            nums[i] = list.get(i);
        }
    }
}

El código es relativamente simple y no hay nada que analizar. Aquí se usa memoria adicional para colocar los elementos de la matriz en la lista. No debería cumplir con los requisitos del problema, pero no hay forma. Después de todo, el algoritmo es demasiado hábil y habrá una solución óptima a continuación.

  • Análisis de complejidad
  1. Complejidad temporal: O (nnn) = O (n). for La complejidad de tiempo del bucle es O (n) y se utilizan un total de tres bucles for.
  2. Complejidad espacial: O (n). El espacio requerido por la Lista es igual al número de elementos en nums.
  • Resultados de la

Solución de referencia

  • Ideas

Esta pregunta proporciona las siguientes dos ideas:

  1. Doble ciclo:
    violencia, el primer ciclo es el número que debe desplazarse hacia la derecha, y el segundo ciclo mueve todos los valores de los elementos a la posición correcta (esto requiere reflexión, debería ser concebible, pero no recomendable).
  2. Voltear:
    arr = [1,2,3,4,5] - desplaza dos bits a la derecha -> [4,5,1,2,3], asumiendo n = longitud de arr., K = número de desplazamiento a la derecha, Disponible:

Voltea los elementos con índice [0, n-1] -> [5,4,3,2,1]

Voltea los elementos entre índice [0, k-1] -> [4,5,3,2,1]

Voltea los elementos entre índice [k, n-1] -> [4,5,1,2,3]

Girar una matriz es en realidad dividir la matriz en dos partes. La clave para resolver el problema es
mover la última parte al frente mientras se asegura el orden original . El giro general de la matriz satisface el segundo elemento, pero altera el
orden original de la matriz , por lo que las dos partes se voltean nuevamente en este momento para restaurarlas al orden original (después de voltear y
luego voltear, se restaurará el orden original ).

  • Código

    /**
     * 双重循环
     * 时间复杂度:O(kn)
     * 空间复杂度:O(1)
     */
    public void rotate_1(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        for (int i = 0; i < k; i  ) {
            int temp = nums[n - 1];
            for (int j = n - 1; j > 0; j--) {
                nums[j] = nums[j - 1];
            }
            nums[0] = temp;
        }
    }

    /**
     * 翻转
     * 时间复杂度:O(n)
     * 空间复杂度:O(1)
     */
    public void rotate_2(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }


    private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start  ] = nums[end];
            nums[end--] = temp;
        }
    }

  • Análisis de complejidad de algoritmos

Doble para bucle:

  • Complejidad de tiempo: O (n ∗ k)
  • Complejidad espacial: O (1)

Dar la vuelta:

  • Complejidad del tiempo: O (n)
  • Complejidad espacial: O (1)

Resultados de la

Resultados de la ejecución del volteo:

Observaciones finales

Mis amigos pueden sentirse muy inteligentes después de ver la solución de voltear, cómo se les ocurrió. No creo que debamos estar demasiado enredados en esto. Nos contactamos con el problema del algoritmo en sí, que es un proceso deliberado de mejora. Si hacemos más, naturalmente tendremos ideas.
[Este artículo se publicó por primera vez en este sitio, indique la fuente para la reimpresión]: http://coderluo.top

Si está interesado en el artículo, puede seguirme en WeChat para intercambiar y aprender juntos:Código de escaneo de WeChat

Supongo que te gusta

Origin blog.csdn.net/taurus_7c/article/details/102768218
Recomendado
Clasificación