leetcode 第 306 场算法比赛

作者: | 更新日期:

进入前百名的机会,翻车了

本文首发于公众号:天空的代码世界,微信号:tiankonguse

零、背景

这次比赛最后一题有点难度,是数位 DP,可惜我也花费了不少时间。

一、矩阵中的局部最大值

题意:给一个 n*n 的矩阵,求一个 (n-2)*(n-2) 的矩阵,矩阵的值是上下左右 9 个方格的最大值。

思路:按照题意四层循环求最值即可。

复杂度:O(3^2 * n^2)

二、边积分最高的节点

题意:给一个有向图,每个节点都有一个出边。
每个节点的得分是所有入度节点编号之和。
求最大得分的编号,有相等得分时返回编号最小的那个。

思路:遍历所有边计算出每个节点的得分,再循环一遍求答案即可。

注意事项:得分可能大于 32 位最大值,需要使用 64 位整数。

三、根据模式串构造最小数字

题意:给一个长度为 n 的只包含ID的字符串,I代表相邻两个数字是大于关系,D是小于关系。
求构造一个长度为 n+1 的数组,使得相邻数字的关系满足输入字符串的规则。

思路:本想使用动态规划来做这道题。
但是考虑到这是第三题,显然不需要这么复杂。

心中大概计算了下,排列组合共有9! 中情况,但是在输入规则的限制下,数据量会快速衰减,搜索不会超时。
于是我便暴力搜索来做了。

不完备的大致推导:

对于相邻两个数字,不是大于就是小于,共有A(n, 2)中情况。
但是确定了大小关系,满足要求的情况就是 C(n, 2)个了。

规则每多一位,数据量就减半,所以大概满足要求的答案个数是 A(n)/2^n个。

再加上是求满足规则的字典序最小的那个,枚举会很快遇到答案,之后就不需要枚举了,所以速度会更快。

四、统计特殊整数

题意:如果一个整数里面各位的数字都不同,则称为特殊数。
[1, n]区间内,特殊数的个数。

思路:典型的数位动态规划,一个 DFS 搞定。

数位动态规划万能模板如下。

假设询问的 n 长度为 L, 最高位数字为 k,则答案分三种情况。

首先答案分两种情况:

第一种情况:[1,10^L] 的数字,最高位不能有前导零,之后可以有 0。
答案固定,直接推导公式计算即可。

第二种情况: 数字为 k 位且与 n 有相同前缀的。
由于位数为 L,所有共有 L 中相同前缀。
从最高位到最低位,枚举处理每一个前缀的情况。

前缀固定后,假设前缀是 k0 k1 ... ka,剩余的长度为 len。
使得 k0 k1 ... ka-1 固定,枚举 ka 这一位,枚举值为 [1, ka-1]
枚举之后,剩余的位数任意选择,求满足规则的个数。

复杂度:O(n * L)

五、最后

这次比赛会卡不少人。
第二题会有人遇到越界的问题,比如我就遇到了。
第三题会有人不敢暴力搜索,动态规划有太复杂,会浪费不少时间。
第四题经典的数位DP,属于高级动态规划,也会卡主一些人。

这样看来,这次比赛的质量还算可以,不过我也被卡主了。

加油,算法人。

《完》

-EOF-

本文公众号:天空的代码世界
个人微信号:tiankonguse
公众号ID:tiankonguse-code

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越