LeetCode Weekly Competition 348 (2023/06/05) デジタルDPテンプレートは学習しましたか?

この記事にはAndroidFamily、技術的および職場の問題が含まれています。公式アカウント [Peng Xurui] に注目し、Knowledge Planet に参加して質問してください。

ウィークリー 348 概要

T1. 文字列の長さを最小限に抑える (中)

  • タグ: ハッシュ テーブル、カウント

T2.セミオーダーアレンジ(簡単)

  • タグ: ハッシュテーブル

T3. クエリ後の行列の合計 (中)

  • タグ: ハッシュテーブル

T4. 整数の数を数える (ハード)

  • タグ: デジタル DP、建設


T1. 文字列の長さを最小限に抑える (中)

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

問題の解決策 (ハッシュ テーブル + カウント)

文字数が何文字であっても、最後には 1 文字が残るため、文字の種類の数だけを記録する必要があります。

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

複雑さの分析:

  • 時間計算量: O ( n ) O(n)O ( n )
  • 空間の複雑さ: O ( n ) O(n)O ( n )

T2.セミオーダーアレンジ(簡単)

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

解決策(シミュレーション)

考慮する必要があるのは 1 と n だけで、各演算は 1 を左に 1 ビット移動することも、n を右に 1 ビット移動することもできますが、1 と n の移動方向が交差することを考慮すると、演算の回数は一度減りました。

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
    }
}

複雑さの分析:

  • 時間計算量: O ( n ) O(n)O ( n )
  • 空間複雑さ: O ( 1 ) O(1)

T3. クエリ後の行列の合計 (中)

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

解決策(ハッシュテーブル)

この質問には少し逆の考え方が必要です。後の操作で前の操作がカバーされるため、逆の順序でたどって次の内容を維持します。

  • rowSet: 演算対象の行番号(逆順)
  • ColSet: 演算対象列番号(逆順)

この場合、各行操作で埋められる回数は、その行で操作されていない列の数になり、各行操作で埋められる回数は、操作されていない行の数になります。コラムで操作されます。

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
    }
}

複雑さの分析:

  • 時間計算量: O ( q ) O(q)( q )
  • 空間計算量: O ( n + q ) O(n + q)O ( n+q )

T4. 整数の数を数える (ハード)

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

問題解決(デジタルDP)

1. 条件を満たす [1,n] 内の適切な整数を表す f(n) を定義すると、元の問題の解は次のようになります: f(num2) - f(num1) + if(num1)

2. デジタル DP を使用します。

n = 234 を例に挙げます

  • isLimit: 上位ビットが現在のビットを制約するかどうか。たとえば、百の位に 2 を入力した場合、十の位には 0 ~ 3 のみを入力できます。それ以外の場合は、0 ~ 9 を入力できます。
  • isNum: 上位の数字が数字であるかどうか、この質問では先頭の 0 を考慮しません。

3. 条件を満たす部分問題の数を示すために dfs(i:Int, sum:Int, isLimit:Int) を定義します。

4. メモでは、isLimit が true に設定されたサブ質問は 1 回だけ再帰され、記憶されたディメンションを isLimit に提供する必要はありません。

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)
    }
}

複雑さの分析:

  • 時間計算量: O ( 10 ⋅ n ⋅ m ) O(10 n m)O ( 10 メートル
  • 空間計算量: O ( n ⋅ m ) O(n m)O ( n メートル

過去のレビュー

おすすめ

転載: blog.csdn.net/pengxurui/article/details/131039340