leetcode 第 417 场算法比赛

作者: | 更新日期:

这次比赛其实算两道题,一道滑动窗口,一道递推,还都不错的,适合用来当做面试题。

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

零、背景

这次比赛题目不难,但是我失误较多,比如排名靠后了。

A: 模拟。
B: 暴力枚举。
C: 滑动窗口。
D: 递推。

排名:137
代码地址: https://github.com/tiankonguse/leetcode-solutions/tree/master/contest/4/417

一、找出第 K 个字符 I

题意:原始字符串长度为1,每次操作将字符串的所有字符加一后追加到原始字符串上。
求当字符串长度不小于k时,第 k 个字符是多少。

思路:标准做法是递推,不过这里数据里比较少,可以按题意模拟构造出字符串,然后输出第k个位置的答案。

二、元音辅音字符串计数 I

题意:给一个字符串,求所有包含5个元音字母且辅音个数恰好是 k 个子字符串个数。

思路:标准做法是滑动窗口,不过这里数据里较少,可以暴力枚举子字符串判断是否满足要求。

三、元音辅音字符串计数 II

题意:给一个字符串,求所有包含5个元音字母且辅音个数恰好是 k 个子字符串个数。

思路:与第二题一样,不过数据范围变大,需要使用滑动窗口来做。

预处理:预处理出每个前缀的辅音个数posToNum以及所有辅音个数首次出现的位置numToPos
所有辅音个数首次出现位置的含义是,第1次出现的位置,第2次出现的位置等等。

滑动窗口:确定左边界 l,先找到包含5个元音的第一个右边界 r。
上面这个边界信息[l,r)是可以使用滑动窗口来供下个左边界使用的。

元音的边界确定后,需要下面四步来找到答案的左右边界。

1、通过a=posToNum[l-1]得知上个位置的辅音个数。
2、通过 L=numToPos[a+k] 来找到第一个满足 k 个辅音的左边界。
3、通过 R=numToPos[a+k+1]-1 来找到最后一个满足 k 个辅音的右边界。
4、答案就是 [l,r)[l,R]的交集。

注意实现:辅音的边界可能不存在,建议先通过整个后缀来判断是否存在边界来剪枝。

四、找出第 K 个字符 I

题意:原始字符串长度为1,有两个操作。
操作1:将字符串保持不变追加到原始字符串上。
操作2:将字符串的所有字符加一后追加到原始字符串上。
告诉你操作列表,问当字符串长度不小于k时,第 k 个字符是多少。

思路:逆向递推。

假设当前求第 kn 个字符的答案,先计算出此时,字符串的长度 N 和操作次数 n。
应该满足这个关系:N/2 < kn <= N,即 kn 在字符串的右半部。

首先需要递归求出第 kn-N/2个字符的答案。

如果第 n 次是复制保持不变,则第 kn 个字符与第 k-N/2 个字符的值相等。
如果第 n 次复制时加1,则第 k 个字符为第k-N/2个字符的值加1。

代码实现的时候,如果使用代码递归,就简单一些。
如果使用循环递推,则需要累计加一的次数,最终根据加一的次数,计算出答案。

五、最后

这次比赛其实算两道题,一道滑动窗口,一道递推,还都不错的,适合用来当做面试题。

《完》

-EOF-

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

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

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

tiankonguse +
穿越