大家好,我是 @负雪明烛。点击右上方的「+关注」↗,优质题解不间断!
题目大意
语文课代表来分析一下题意。
把 个英文字母排列成一个圆圈 ⭕️,叫做 。
另外给了一个字符串 ,让我们找出 的所有子串中,在 中的有多少个。
由于 的子串可能会有重复的,因此重复的子串只算 个。
注:子串与子序列的区别: 子串要求连续,子序列不需要连续。
解题方法
分析
遇到子串,一般会想到「滑动窗口」和「动态规划」。
本地的思想其实是「滑动窗口」和「动态规划」相结合。
子串相关的动态规划,一般状态的定义都是「以位置 作为结尾的、符合要求的子串长度」。
这样定义,主要是为了简化,因为知道了 以后,很容易就能得到 。
比如对于本题,我们把状态定义为「中,以位置 作为结尾的、在 中存在的最长子串长度」。
那么在已知了 以后,得到 时,无非两种情况:
- 当在 中, 是 的下一个字符,那么说明能连接上,于是 $dp[i + 1] = dp[i] + 1$。
- 当在 中, 不是 的下一个字符,那么说明能连接不上,于是 $dp[i + 1] = 1$。
看下面的动图,就明白了。
当出现重复的字符时,我们要取最大。
代码
使用一个字典保存以每个字符为结尾的最长字符串长度。
Python 代码如下:
class Solution:
def findSubstringInWraproundString(self, p):
"""
:type p: str
:rtype: int
"""
count = collections.defaultdict(int)
N = len(p)
_len = 0
for i in range(N):
if i > 0 and (ord(p[i]) - ord(p[i - 1]) == 1 or (p[i] == 'a' and p[i - 1] == 'z')):
_len += 1
else:
_len = 1
count[p[i]] = max(count[p[i]], _len)
return sum(count.values())
复杂度
- 时间复杂度:,是字符串长度。
- 空间复杂度:,只用了一个字典,字典的大小为 $26$。
总结
- 字符串结合动态规划的套路。
我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
- 在刷题的时候,如果你不知道该怎么刷题,可以看 LeetCode 应该怎么刷?
- 如果你觉得题目太多,想在短时间内快速提高,可以看 LeetCode 最经典的 100 道题。
- 送你一份刷题的代码模板:【LeetCode】代码模板,刷题必会
- 我写的 1000 道 LeetCode 题解,都在这里了,免费拿走。