LeetCode-992. Subarreglos con K códigos y análisis de enteros diferentes (Java)

LeetCode-992. Subarreglos con K diferentes enteros [Subarreglos con K diferentes enteros] -análisis y código [Java]

1. Tema

Dada una matriz de enteros positivos A, si el número de enteros diferentes en una submatriz de A resulta ser K, entonces esta submatriz continua, no necesariamente independiente de A, se llama una buena submatriz.
(Por ejemplo, hay 3 números enteros diferentes en [1,2,3,1,2]: 1, 2 y 3.)
Devuelve el número de subarreglos buenos en A.

Ejemplo 1:

输入:A = [1,2,1,2,3], K = 2
输出:7
解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].

Ejemplo 2:

输入:A = [1,2,1,3,4], K = 3
输出:3
解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4].

inmediato:

  • 1 <= A. longitud <= 20000
  • 1 <= A [i] <= A. longitud
  • 1 <= K <= A. longitud

Fuente: LeetCode (LeetCode)
Enlace: https://leetcode-cn.com/problems/subarrays-with-k-different-integers Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Dos, análisis y código

1. Ventana corredera

(1) Pensando

De acuerdo con el problema, se pueden encontrar las características de una buena submatriz: cuando se determina el límite derecho, los extremos del límite izquierdo que satisfacen diferentes K enteros están en un intervalo continuo.
Por lo tanto, se pueden diseñar dos ventanas deslizantes con el mismo límite derecho de modo que haya K y K-1 números enteros diferentes en el intervalo. Cuando el borde derecho se mueve cada vez, la diferencia entre las posiciones de los bordes izquierdos de las dos ventanas es el número de submatrices buenas debajo del borde derecho actual.

(2) Código

class Solution {
    
    
    public int subarraysWithKDistinct(int[] A, int K) {
    
    
        int n = A.length, ans = 0;
        //为滑动窗口设计2个左指针,指向不同整数个数为K和K-1的子数组左边界
        int[] num1 = new int[n + 1];
        int[] num2 = new int[n + 1];
        for (int i = 0; i <= n; i++) {
    
    
            num1[i] = 0;
            num2[i] = 0;
        }
        int l1 = 0, l2 = 0, r = 0;
        int diff1 = 0, diff2 = 0;
        while (r < n) {
    
    
            if (num1[A[r]]++ == 0)
                diff1++;
            if (num2[A[r++]]++ == 0)
                diff2++;
            while (diff1 > K)
                if (--num1[A[l1++]] == 0)
                    diff1--;
            while (diff2 > K - 1)
                if (--num2[A[l2++]] == 0)
                    diff2--;
            ans += l2 - l1;
        }
        return ans;
    }
}

(3) Resultados

Tiempo de ejecución: 4 ms, superando al 97,66% de los usuarios
en todas las presentaciones de Java ; consumo de memoria: 41,8 MB, superando al 71,05% de los usuarios en todas las presentaciones de Java.

Tres, otro

Nada.

Supongo que te gusta

Origin blog.csdn.net/zml66666/article/details/113839272
Recomendado
Clasificación