LeetCode Weekly Competition 348 (2023/06/05) ¿Ha aprendido la plantilla de DP digital?

Este artículo ha incluido AndroidFamily , problemas técnicos y de lugar de trabajo, preste atención a la cuenta oficial [Peng Xurui] y únase a Knowledge Planet para hacer preguntas.

Resumen semanal 348

T1. Minimizar la longitud de la cadena (Medio)

  • Etiquetas: tabla hash, conteo

T2 Arreglo semiordenado (Fácil)

  • Etiquetas: tabla hash

T3 La suma de la matriz después de la consulta (Medio)

  • Etiquetas: tabla hash

T4 Contar el número de enteros (Hard)

  • Etiquetas: DP digital, construcción


T1. Minimizar la longitud de la cadena (Medio)

https://leetcode.cn/problems/minimize-string-length/

Solución del problema (tabla hash + conteo)

No importa cuántos caracteres haya, al final quedará 1 carácter, por lo que solo se debe registrar la cantidad de tipos de caracteres:

class Solution {
    
    
    fun minimizedStringLength(s: String): Int {
    
    
        return s.toHashSet().size
    }
}

Análisis de complejidad:

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

T2 Arreglo semiordenado (Fácil)

https://leetcode.cn/problems/semi-ordered-permutation/

Solución (simulación)

Solo necesitamos considerar 1 y n, y cada operación puede mover 1 a la izquierda un bit, o mover n a la derecha un bit, pero considerando que las direcciones de movimiento de 1 y n se cruzan, el número de operaciones debe ser reducido una vez.

class Solution {
    
    
    fun semiOrderedPermutation(nums: IntArray): Int {
    
    
        val n = nums.size
        val i = nums.indexOf(1)
        val j = nums.indexOf(n)
        return i + (n - 1 - j) - if (i > j) 1 else 0
    }
}

Análisis de complejidad:

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

T3 La suma de la matriz después de la consulta (Medio)

https://leetcode.cn/problems/sum-of-matrix-after-queries/

Solución (tabla hash)

Esta pregunta requiere un poco de pensamiento inverso. Las operaciones posteriores cubrirán las operaciones anteriores, por lo que recorremos en orden inverso y mantenemos:

  • rowSet: número de fila operada (en orden inverso)
  • colSet: número de columna operada (orden inverso)

Entonces, el número de veces que se puede completar en cada operación de fila es el número de columnas que no se han manipulado en la fila, y el número de veces que se puede completar en cada operación de fila es el número de filas que no se han manipulado. manipulado en la columna.

class Solution {
    
    
    fun matrixSumQueries(n: Int, queries: Array<IntArray>): Long {
    
    
        var ret = 0L
        val visitSet = Array(2) {
    
     HashSet<Int>() }
        for (query in queries.reversed()) {
    
    
            val type = query[0]
            val index = query[1]
            val value = query[2]
            // 重复操作
            if (visitSet[type].contains(index)) continue
            // 这次操作可以填充的数字
            ret += 1L * (n - visitSet[type xor 1].size) * value
            visitSet[type].add(index)
        }
        return ret
    }
}

Análisis de complejidad:

  • Complejidad del tiempo: O ( q ) O(q)O ( q )
  • Complejidad del espacio: O ( n + q ) O(n + q)O ( n+q )

T4 Contar el número de enteros (Hard)

https://leetcode.cn/problems/count-of-integers/

Problema Solución (DP Digital)

1. Defina f(n) para representar un buen entero en [1,n] que satisfaga las condiciones, entonces la solución al problema original es: f(num2) - f(num1) + if(num1)

2. Utilice DP digital:

Tome n = 234 como ejemplo

  • isLimit: si el bit alto restringe el bit actual. Por ejemplo, si completa 2 para el dígito de las centenas, solo puede completar 0-3 para el dígito de las decenas, de lo contrario, puede completar 0-9
  • isNum: si el dígito alto es un número, no considere el 0 inicial para esta pregunta

3. Defina dfs(i:Int, sum:Int, isLimit:Int) para indicar el número de subproblemas que satisfacen la condición

4. En el memorándum, la subpregunta con isLimit establecido en verdadero solo se repetirá una vez, y no es necesario proporcionar isLimit con una dimensión memorizada:

class Solution {
    
    

    private val MOD = 1000000007

    fun count(num1: String, num2: String, min_sum: Int, max_sum: Int): Int {
    
    
        return count(num2, min_sum, max_sum) - count(num1, min_sum, max_sum) + check(num1, min_sum, max_sum)
    }

    private fun check(num: String, min_sum: Int, max_sum: Int): Int {
    
    
        var sum = 0
        for (c in num) sum += c - '0'
        return if (sum in min_sum..max_sum) 1 else 0
    }

    // 数位 DP
    private fun count(num: String, min_sum: Int, max_sum: Int): Int {
    
    
        fun dfs(num: String, memo: Array<IntArray>, i: Int, sum: Int, isLimit: Boolean): Int {
    
    
            // 终止条件
            if (sum > max_sum) return 0
            if (i == num.length) return if (sum >= min_sum) 1 else 0
            // 备忘录
            if (!isLimit && memo[i][sum] != -1) return memo[i][sum]
            // 上界
            val upper = if (isLimit) num[i] - '0' else 9
            var ret = 0
            for (choice in 0 .. upper) {
    
    
                ret = (ret + dfs(num, memo, i + 1, sum + choice , isLimit && choice == upper)) % MOD
            }
            // 备忘录
            if (!isLimit) memo[i][sum] = ret
            return ret
        }

        val n = num.length
        val m = Math.min(9 * n, max_sum) + 1
        return dfs(num, Array(n) {
    
     IntArray(m) {
    
     -1 } }, 0, 0, true)
    }
}

Análisis de complejidad:

  • Complejidad del tiempo: O ( 10 ⋅ n ⋅ m ) O(10 n m)O ( 10 norte m )
  • Complejidad espacial: O ( n ⋅ m ) O(n m)O ( norte m )

Revisión anterior

Supongo que te gusta

Origin blog.csdn.net/pengxurui/article/details/131039340
Recomendado
Clasificación