1.1.3 Matrices - Cuadrado de x (Leetcode 69)

1. Tema

Enlace de Leetcode
Dado un número entero no negativo x, calcule y devuelva la raíz cuadrada aritmética de x.

Dado que el tipo de retorno es un número entero, solo se conserva la parte entera del resultado y se descarta la parte decimal.

Nota: No se permiten funciones exponenciales integradas ni operadores como pow(x, 0,5) o x ** 0,5.

Ejemplo 1:

Entrada: x = 4
Salida: 2
Ejemplo 2:

Entrada: x = 8
Salida: 2
Explicación: La raíz cuadrada aritmética de 8 es 2,82842…, como el tipo de retorno es un número entero, la parte decimal se redondeará.

pista:

0 <= x <= 2 31 - 1

2. Idea

Dado que solo se mantiene la parte entera, ans es el mayor valor de k que satisface k 2 ≤ x

Solución 1: encuentre la raíz cuadrada de la función logarítmica
inserte la descripción de la imagen aquí
[Nota: el valor devuelto es un número de punto flotante, lo que causará problemas de precisión]

Solución 2: búsqueda binaria k

Solución 3: método de iteración de Newton

  1. Transformar el problema en resolver el punto cero de la función
    inserte la descripción de la imagen aquí
  2. La esencia del método iterativo de Newton es acercarse rápidamente a cero desde el valor inicial con la ayuda de la serie de Taylor.
    inserte la descripción de la imagen aquí
  3. Proceso de implementación
    inserte la descripción de la imagen aquí
  4. detalles de implementacion
    inserte la descripción de la imagen aquí

3. Implementación del código

Solución 2: búsqueda binaria k

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        int left = 0;
        int right = x;
        int ans = -1;

        while(left <= right){
    
    
            int middle = left + (right - left) / 2;
            if((long long)middle*middle <= x){
    
    
                ans = middle; // 满足条件的k, 最后更新得到ans
                left = middle + 1;
            }else{
    
    
                right = middle - 1;
            }
        }

        return ans;
    }

};

Análisis de Complejidad

  • Complejidad del tiempo: O ( logx ) O(logx)O ( l o g x ) es el número de veces necesario para la búsqueda binaria.
  • Complejidad del espacio: O ( 1 ) O(1)O ( 1 )

Solución 3: método de iteración de Newton

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        if (x == 0) return 0;

        // 设置迭代初始值
        double x0 = x;
        double C = x;

        while(true){
    
    
            double x1 = 0.5 * (x0 + C/x0); // 根据公式得到下一个点x(i+1)
            if(fabs(x1 - x0) < 1e-7) break;
            x0 = x1; // 更新点xi
        }

        return int(x0);

    }

};

Análisis de Complejidad

  • Complejidad del tiempo: O ( logx ) O(logx)O ( log x ) , este método es cuadráticamente convergente, más rápido que la búsqueda binaria .
  • Complejidad del espacio: O ( 1 ) O(1)O ( 1 )

4. Resumen

1. Juicio de desbordamiento

(long long)middle*middle <= x
  • Aquí el rango de valores de medio es 0 <= medio <= 2 31 - 1, luego 0 <= medio * medio < 2 62
  • Y el rango de valores de la variable int es 2 31 <= medio <= 2 31
  • Debido a que el tipo de variable debe convertirse en largo

2. Conociendo la pendiente de la recta y un punto de la recta, la fórmula de expresión de la ecuación de la recta

3. abs() y fabs()

  • abs() se usa principalmente para encontrar el valor absoluto de un número entero, en el archivo de encabezado "stdlib.h" (o).
  • Y fabs() es principalmente para buscar el valor absoluto de tipo doble y flotante con requisitos de mayor precisión, en el archivo de encabezado <cmath>.
  • Ambos se pueden usar cuando solo #include <cmath>.

4. Corregir la escritura idiomática de las matemáticas

 double x1 = 1/2 * (x0 + C/x0); // 根据公式得到下一个点x(i+1)

Escrito de esta forma, se repetirá para siempre, ¡porque 1/2 aquí obtendrá 0!

Supongo que te gusta

Origin blog.csdn.net/weixin_46297585/article/details/123218175
Recomendado
Clasificación