Pregunta diaria de Leetcode - 189. Matriz de rotación (entrevista clásica de 150 preguntas)

1. Descripción del tema y requisitos

189. Rotar matriz - LeetCode

Tema Descripción

Dada una matriz de enteros  nums, gire los elementos de la matriz hacia la derecha  k en posiciones donde es  k un número no negativo.

ejemplo

Ejemplo 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

Ejemplo 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

pista

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

2. Ideas para resolver problemas

Idea general:

       De acuerdo con el análisis del tema, necesitamos colocar los elementos k detrás de la matriz en el orden original de acuerdo con la cantidad de rotación k, y mover los elementos al frente de la matriz en orden. Por ejemplo, k=1, el elemento de la matriz es 1234567, luego el resultado después de la rotación debe cambiarse a 5671234.

       Para realizar este proceso, la forma más sencilla es usar directamente otra matriz, almacenar los elementos de la matriz original en la matriz auxiliar en el orden posterior a la rotación y luego asignar el valor de la matriz auxiliar a la matriz. La posición correspondiente a la rotación del elemento se puede obtener mediante (i+k)%numsSize. La complejidad temporal de este método es O(n) y la complejidad espacial también es O(n). ¿Hay alguna manera de reducir la complejidad del espacio utilizado? Porque cuando los elementos de la matriz son demasiado grandes, se requiere un gran espacio auxiliar.

       Observamos 1234 567 y 567 1234, y podemos encontrar que la rotación es equivalente a poner los k elementos detrás del arreglo al frente según el valor de k, entonces también podemos dividir directamente el arreglo en dos partes, cómo hacerlo siga el orden correspondiente después de dividir en dos partes Bueno, obviamente es difícil lograr el orden correspondiente dividiendo en dos partes primero. Entonces pensamos que los siguientes elementos k deben colocarse en el frente, y los elementos anteriores deben colocarse en la parte posterior, entonces también podríamos voltear la matriz primero, es decir, se convierte en "orden inverso". Luego, la matriz se divide en dos partes. En este momento, los elementos contenidos en cada parte son correctos, pero el orden es incorrecto, porque hemos realizado una ordenación por volteo en él, por lo que solo necesitamos voltear las dos partes nuevamente.

Pasos específicos:

Utilice matrices auxiliares:

① Definir matriz auxiliar

② Asigne valores a la matriz auxiliar de acuerdo con el objetivo

③ Utilice la matriz auxiliar para actualizar la matriz original

Array Flip: [Hacer cambios en la matriz original]

① Determine si la cantidad de rotación es mayor que el elemento de la matriz, si es mayor que eso, tome el resto (porque no hay tantos bits para la rotación)

② Voltee la matriz completa (usando punteros dobles para intercambiar el primer y el último elemento)

③ Voltea los primeros k elementos de la matriz volteada

④ Voltear la segunda mitad de la matriz volteada


3. Código específico [lenguaje C]

①  Usar matriz auxiliar   [tiempo O(n) espacio O(n)]

void rotate(int* nums, int numsSize, int k){
    if( k ==0 || numsSize == 1)   return;
    int tem[numsSize];//定义辅助数组
    for(int i=0;i<numsSize;i++){
        tem[(i+k)%numsSize]=nums[i];//在辅助数组中将每一个元素放到对应位置
    }
    for(int i=0;i<numsSize;i++){//复制数组
        nums[i]=tem[i];
    }
}

②Cambio de matriz: [cambiar la matriz original]  [tiempo O(n) espacio O(1)]

void swap(int* a, int* b) //传址
{
    int t = *a;
    *a = *b;
    *b = t;
}

void reverse(int* nums, int left, int right) //对数组进行翻转
{
    while (left < right) 
    {
        swap(&nums[left], &nums[right]);//将首尾两个数进行交换
        left += 1;
        right -= 1;
    }
}

void rotate(int* nums, int numsSize, int k){
    k%=numsSize;  //避免出现轮转量大于数组元素的情况
    if( k ==0 || numsSize == 1)   return;
    //翻转整个数组
    reverse(nums, 0, numsSize - 1);
    //将翻转后的前面部分变回原始顺序
    reverse(nums, 0, k - 1);
    //将翻转后的后面部分变回原始顺序
    reverse(nums, k, numsSize - 1);
}

Supongo que te gusta

Origin blog.csdn.net/m0_59800431/article/details/131551454
Recomendado
Clasificación