本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 加入知识星球提问!

周赛 348 概览

T1. 最小化字符串长度(Medium)

  • 标签:散列表、计数

T2. 半有序排列(Easy)

  • 标签:散列表

T3. 查询后矩阵的和(Medium)

  • 标签:散列表

T4. 统计整数数目(Hard)

  • 标签:数位 DP、构造


T1. 最小化字符串长度(Medium)

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

题解(散列表 + 计数)

无论每个字符有多少,最终每个字符都会剩下 1 个,因此只需要记录字符种类数:

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

复杂度分析:

  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

T2. 半有序排列(Easy)

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

题解(模拟)

我们只需要考虑 1 和 n,每次操作可以把 1 向左边移动一位,或者将 n 向右移动一位,但是考虑到 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(1)$

T3. 查询后矩阵的和(Medium)

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(n + q)$

T4. 统计整数数目(Hard)

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

题解(数位 DP)

1、定义 f(n) 表示 [1,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(n·m)$

往期回顾

LeetCode 周赛 348(2023/06/05)数位 DP 模板学会了吗的更多相关文章

  1. HDU 2089 不要62(数位dp模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求区间内不包含4和连续62的数的个数. 思路: 简单的数位dp模板题.给大家推荐一个好的讲解博客.h ...

  2. POJ 3286 How many 0's(数位DP模板)

    题目链接:http://poj.org/problem?id=3286 题目大意: 输入n,m,求[n,m]的所有数字中,0出现的总数是多少,前导零不算. 解题思路: 模板题,设dp[pos][num ...

  3. 数位dp模板 [dp][数位dp]

    现在才想到要学数位dp,我是不是很弱 答案是肯定的 以一道自己瞎掰的题为模板 //题: //输入数字n //从0枚举到n,计算这n+1个数中含有两位数a的数的个数 //如12930含有两位数93 #i ...

  4. 51nod 1009 数字1的数量(数位dp模板)

    给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1.   数位dp的模板题   ...

  5. 数位DP模板详解

    // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位) // status = 要达到的状态,如果为1则可以认为找到了答案,到时候用来返回, // 给计 ...

  6. 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...

  7. 【hdu6148】Valley Numer【数位dp模板题】

    题意 对于每组数据给出一个整数n(length(n)<=100),找出不大于n的数字中有多少是Valley Numer.对于Valley的定义是它每一位的数字要么是递增,要么是递减,要么是先递减 ...

  8. HDU 3555 Bomb(数位DP模板啊两种形式)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 Problem Description The counter-terrorists found ...

  9. HDU 2089 不要62 数位DP模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 参考博客:https://www.cnblogs.com/HDUjackyan/p/914215 ...

  10. HDU - 4722 Good Numbers 【找规律 or 数位dp模板】

    If we sum up every digit of a number and the result can be exactly divided by 10, we say this number ...

随机推荐

  1. MySQL 查询执行的过程

    查询的生命周期大致可以按照顺序来看:从客户端到服务端,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中 "执行" 可以认为是整个生命周期中最重要的阶段,其中包括 ...

  2. MySQL高可用架构-MMM、MHA、MGR、分库分表

    总结 MMM是是Perl语言开发的用于管理MySQL主主同步架构的工具包.主要作用:管理MySQL的主主复制拓扑,在主服务器失效时,进行主备切换和故障转移. MMM缺点:故障切换可能会丢事务(主备使用 ...

  3. Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor

    给大家推荐两款 Mac 上的音频转换器,这两款转换器都可以转换苹果音乐,iTunes歌曲或者一些常规的音轨到MP3, FLAC, WAV, M4A, AAC格式等等,转换后我们就可以在所有的设备和播放 ...

  4. NoSQL之 Redis配置与优化

    目录 一.缓存概念 1.1 系统缓存 1.1.1buffer与cache 1.2 缓存保存位置及分层结构 1.2.1 DNS缓存 1.2.2 应用层缓存 1.2.3数据层缓存 1.2.4 硬件缓存 二 ...

  5. Goalng:基础复习一遍过

    Go(又称Golang)是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. 剖析 Hello world 新建文件 main.go 写入以下内容: package ma ...

  6. python之爬虫三

    20xpath入门 在编写爬虫程序的过程中提取信息是非常重要的环节,但是有时使用正则表达式无法匹配到想要的信息,或者书写起来非常麻烦,此时就需要用另外一种数据解析方法,也就是本节要介绍的 Xpath ...

  7. git撤销某一次commit提交

    一.使用git rebase命令 如果您想彻底删除 Git 中的某次提交的内容,可以使用 git rebase 命令并将该提交删除. 以下是删除 Git 提交内容的步骤: 找到要删除的提交的哈希值.可 ...

  8. 用CMD或者bat修改host文件

    第一行代码标识 取消host的只读属性 第二行写入 attrib -R C:\WINDOWS\system32\drivers\etc\hosts @echo 127.0.0.1 baidu.com ...

  9. 基于Python的爬虫案例

    案例1:使用爬虫爬取京东华为手机用户评论 本案例借鉴哔哩哔哩博客主视频教程,感谢其教程为我开启了爬虫之旅:https://www.bilibili.com/video/BV1Yt4y1Y7nt?t=3 ...

  10. Go语言微服务框架go-micro(入门)

    Micro用于构建和管理分布式系统,是一个工具集,其中go-micro框架是对分布式系统的高度抽象,提供分布式系统开发的核心库,可插拔的架构,按需使用 简单示例 编写protobuf文件: synta ...