¡La pregunta sobre algoritmo que hizo el entrevistador ayer me hizo llorar! ?

Prefacio

Algoritmo de League of Heroes: el entrenamiento de julio ha comenzado durante 20 días. El entrenamiento de algoritmo de agosto comenzará oficialmente el 1 de agosto. El registro ya comenzó con anticipación. Para conocer los métodos de registro, consulte (Registro de entrenamiento de algoritmo de agosto). Los estudiantes que quieran participar son Se recomienda comenzar temprano. Regístrese, porque para los estudiantes sin base en algoritmos, habrá algún trabajo de preparación por adelantado. Por ejemplo, se necesitan de 1 a 5 días para completar la capacitación previa y la capacitación de nueve días para desarrollar el Hábito de resolver preguntas con anticipación. Será más efectivo participar en el entrenamiento del algoritmo.

1. Preguntas de los fans

  El maestro héroe que conocí ayer en la entrevista obtuvo 2563, es difícil llorar, ¡55555!

2. Leer preguntas con confianza

  ¡Lea la pregunta! Dada una matriz de números enteros y dos números enteros inferior y superior, devuelve el número de pares de números justos. Si el par de números (i, j) satisface las siguientes condiciones, se considera un par de números justos.
  0 <= i < j < n,ylower <= nums[i] + nums[j] <= upper

3. Algoritmo 1 O (n ^ 2)

  Calcule la longitud de la matriz, guárdela en n e inicialice la variable de resultado en 0. Atraviesa el primer subíndice i de la enumeración y atraviesa el segundo subíndice j de la enumeración. Si inferior ≤ num [i] + num [j] ≤ superior, indica un conjunto de pares de números legales (i, j). El contador de resultados se incrementa en uno y se devuelve este contador, que es la respuesta que requerimos. Funciona sin problemas:

class Solution:
    def countFairPairs(self, nums, lower, upper):
        n = len(nums)
        ans = 0
        for i in range(n):
            for j in range(n):
                if(lower <= nums[i] + nums[j] <= upper):
                    ans += 1
        return ans

  ah? ¿Mal picante? ? ? Hiss
  oh oh oh oh, i y j están en orden, por lo que j necesita comenzar a enumerar desde i + 1, ¡corre! ¡Muy confiado, envía!

class Solution:
    def countFairPairs(self, nums, lower, upper):
        n = len(nums)
        ans = 0
        for i in range(n):
            for j in range(i+1, n):
                if( lower <= nums[i] + nums[j] <= upper):
                    ans += 1
        return ans

  ¡Caducado! silbido……

4. Algoritmo 2 O (n ^ 2)

  ¡Oh oh oh oh oh! El rango de n es 5 veces 10, O ( n 2 ) O(n^2)O ( n.2 )La complejidad temporal de nums[i] + nums[j]), luego asigna j a l y salta del bucle (lo que indica que todos los js posteriores cumplen las condiciones); luego j se enumera de n-1 a i+ 1 en orden inverso, una vez que se descubre que se cumplen las condiciones ( nums [i] + nums [j] ≤ superior), asigne j a r y salte del bucle (lo que indica que todos los js anteriores cumplen las condiciones).
  Entonces, si l <= r, significa que todos los pares de números entre l y r satisfacen la situación, se acumulan en ans y
se ejecutan. No hay problema. ¡Envíe!

class Solution:
    def countFairPairs(self, nums, lower, upper):
        n = len(nums)
        nums.sort()
        ans = 0
        for i in range(n):
            l = -1
            r = -1
            for j in range(i+1, n):
                if lower <= nums[i] + nums[j]:
                    l = j
                    break
            for j in range(n-1, i, -1):
                if nums[i] + nums[j] <= upper:
                    r = j
                    break
            if l != -1 and l <= r:
                ans += r - l + 1
        return ans

  ¡Se agotó el tiempo nuevamente! ……silbido

5. Algoritmo O (nlogn)

  ¡Oh oh oh oh oh! Esto no ha mejorado la complejidad del tiempo. En general, la complejidad del tiempo sigue siendo O (n ^ 2). Elimínelo y comience de nuevo. No quiero renunciar a él. Elimínelo. Si el anterior no se ha ido, ¡el nuevo no vendrá!
  Pruebe el algoritmo de doble puntero que hemos aprendido. Primero puede ordenar los números en orden ascendente. Suponga que count(nums, value) representa una función que calcula los pares de números que satisfacen ≤ valor. Luego calcule el número de pares de números que son ≤ superior y almacenarlos en caché en In b, luego calcular el número de pares de números ≤ inferior - 1, almacenarlos en caché en a y, finalmente, devolver b - a para obtener el resultado que requerimos.
  Menos yo plus.
  Luego implemente esta función, calcule la longitud de nums y guárdela en caché en n, inicialice l a 0, r a n-1 y el resultado ans es 0. Si l <r, determine si nums[l] + nums[r] es menor que Igual al valor, si se cumplen las condiciones, dado que nums está aumentando, significa que nums[l] es fijo, y todos los num[l+1] satisfactorios a nums[r] deben ser ≤ valor. r - l grupos se acumulan en ans; de lo contrario, reduzca el valor de r, salte del bucle cuando l sea igual a r y devuelva el resultado ans. ¡Ejecute y envíe!

class Solution:
    def countLessThan(self, nums, value):
        n = len(nums)
        l = 0
        r = n - 1
        ans = 0
        while l < r:
            if nums[l] + nums[r] <= value:
                ans += r - l
                l += 1
            else:
                r -= 1
        return ans

    def countFairPairs(self, nums, lower, upper):
        b = self.countLessThan(nums, upper)
        a = self.countLessThan(nums, lower-1)
        return b - a

  ¡Nuevamente incorrecto!
  ¡Oh, oh, oh,
  olvidé ordenar!
  ¡Karma negativo! ? !
¡Corre, no hay problema, envía!

class Solution:
    def countLessThan(self, nums, value):
        n = len(nums)
        l = 0
        r = n - 1
        ans = 0
        while l < r:
            if nums[l] + nums[r] <= value:
                ans += r - l
                l += 1
            else:
                r -= 1
        return ans

    def countFairPairs(self, nums, lower, upper):
        nums.sort()
        b = self.countLessThan(nums, upper)
        a = self.countLessThan(nums, lower-1)
        return b - a

¡Aprobado! ¡La!
188 milisegundos ¿
Hay algún margen de optimización?
El algoritmo O (nlogn)
ya es óptimo,
maldita sea,
hay tanta gente por delante, ¿
cómo es posible? !
No se me ocurre nada.
¿Realmente queremos parar aquí?
¿Realmente quieres rendirte?
¿Cómo derrotar a esta gente?
Espere
O (nlogn) es demasiado picante.
Según la experiencia de la pregunta anterior,
la eficiencia de C ++ es obviamente mayor que la de Python.
Simplemente escríbalo en C ++
y definitivamente estará bien.

6. Versión O(nlogn) C++

  Primero escriba la clasificación para no olvidarla: calcule los pares de números menores o iguales a superior, calcule los pares de números menores o iguales a inferior-1, devuelva la diferencia entre los dos e implemente la función de conteo. Básicamente es lo mismo que la idea de Python, que es ajustar la posición del puntero con dos punteros. No hay mucho que decir, simplemente suena suave y fluido. No hay ninguna técnica en general, todo es simplemente emocional.
  ¡Corre, no hay problema, envía!

class Solution {
    
    
public:
    long long countLessThan(vector<int>& nums, int value) {
    
    
        int n = nums.size();
        int l = 0, r = n - 1;
        long long ans = 0;
        while (l < r) {
    
    
            if(nums[l] + nums[r] <= value) {
    
    
                ans += r - l;
                l++;
            }else {
    
    
                r--;
            }
        }
        return ans;
    }
    long long countFairPairs(vector<int>& nums, int lower, int upper) {
    
    
        sort(nums.begin(), nums.end());
        long long b = countLessThan(nums, upper);
        long long a = countLessThan(nums, lower-1);
        return b - a;
    }
};

  ¡Aprobado! ¡124 milisegundos!

7. Versión optimizada de O(nlogn) C++

Sólo derrotó al 93,68% del pueblo ¿
Qué pasó?
Este código ya es muy conciso.
Hiss
, ¿hay alguna forma más eficiente?
¿Quieres rendirte?
¿Te estás rindiendo aquí?
No debería ser así.
Debo estar perdiendo algo. ¿
Qué es?
¿entonces que es?
Espera,
ya que es
entrada y salida de C++, puedes usar
sync_with_stdio y tie
para optimizarlo.
Así, ¿
ejecutarlo
? ? ?
Oh, oh, oh, oh.
La llamada al espacio de nombres debe tener dos puntos
. ¡Simplemente agrégalo y se
ejecutará
!
¡Derrotaste a todos en el mundo! ! !

// 最终版本
class Solution {
    
    
public:
    int fast_io = [](){
    
    
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        return 0;
    }();
    long long countLessThan(vector<int>& nums, int value) {
    
    
        int n = nums.size();
        int l = 0, r = n - 1;
        long long ans = 0;
        while (l < r) {
    
    
            if(nums[l] + nums[r] <= value) {
    
    
                ans += r - l;
                l++;
            }else {
    
    
                r--;
            }
        }
        return ans;
    }
    long long countFairPairs(vector<int>& nums, int lower, int upper) {
    
    
        sort(nums.begin(), nums.end());
        long long b = countLessThan(nums, upper);
        long long a = countLessThan(nums, lower-1);
        return b - a;
    }
};

Supongo que te gusta

Origin blog.csdn.net/WhereIsHeroFrom/article/details/131821566
Recomendado
Clasificación