题目链接: https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string
难度:中等
通过率:35.6%
题目描述:
把字符串 s
看作是"abcdefghijklmnopqrstuvwxyz"的无限环绕字符串,所以 s
看起来是这样的:"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....".
现在我们有了另一个字符串 p
。你需要的是找出 s
中有多少个唯一的 p
的非空子串,尤其是当你的输入是字符串 p
,你需要输出字符串 s
中 p
的不同的非空子串的数目。
注意: p
仅由小写的英文字母组成,p 的大小可能超过 10000。
示例:
示例 1:
**输入:** "a"
**输出:** 1
**解释:** 字符串 S 中只有一个"a"子字符。
示例 2:
**输入:** "cac"
**输出:** 2
**解释:** 字符串 S 中的字符串"cac"只有两个子串"a"、"c"。.
示例 3:
**输入:** "zab"
**输出:** 6
**解释:** 在字符串 S 中有六个子串"z"、"a"、"b"、"za"、"ab"、"zab"。.
思路:
我们只需找以每个字母结尾而形成最长连续的字符串长度就行了!
比如p = 'abcdabc'
,我们前面abcd
部分发现以a
结尾的最长连续字符串长度为1
;以b
结尾的最长连续字符串长度为2
;以c
结尾的最长连续字符串长度为3
;以d
结尾的最长连续字符串长度为4
;而后面的abc
重复前面的字符串。
而最长长度就是以字母结尾可以组成不同字符串的个数,如以d
结尾的最长连续字符串长度为4
,即d, cd, bcd, abcd
,4个不同的字符串。
代码:
class Solution:def findSubstringInWraproundString(self, p: str) -> int:from collections import defaultdictdp = defaultdict(int)dp[p[0]], curMaxLen = 1, 1for idx in range(1, len(p)):if (ord(p[idx]) - ord(p[idx - 1])) % 26 == 1:curMaxLen += 1else:curMaxLen = 1dp[p[idx]] = max(dp[p[idx]], curMaxLen)return sum(dp.values())
换一种写法:
class Solution:def findSubstringInWraproundString(self, p: str) -> int:from collections import defaultdictif not p: return 0dp = defaultdict(int)dp[p[0]], curMaxLen = 1, 1for prev, nxt in zip(p, p[1:]):curMaxLen = curMaxLen + 1 if (ord(nxt) - ord(prev)) % 26 == 1 else 1dp[nxt] = max(dp[nxt], curMaxLen)return sum(dp.values())