题目难度: 中等
原题链接
今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~
你有两个字符串,即 pattern 和 value。 pattern 字符串由字母"a"和"b"组成,用于描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a",“go"是"b”),该字符串也匹配像"a"、"ab"和"b"这样的模式。但需注意"a"和"b"不能同时表示相同的字符串。编写一个方法判断 value 字符串是否匹配 pattern 字符串。
n = ca*lea+cb*leb
O(N^2)
: N 是 value 字符串长度, 外层和内层循环都需要遍历 NO(1)
: 只使用了常数空间的变量class Solution:
def patternMatching(self, pattern: str, value: str) -> bool:
n = len(value)
# 首先统计pattern中a和b的数目ca和cb
cnts = collections.Counter(pattern)
ca, cb = cnts["a"], cnts["b"]
if ca == 0 and cb == 0:
# 特殊情况1: pattern是空字符串, 此时只有当value也是空才返回true
return not value
if ca == 0:
# 特殊情况2: pattern中没有a, 则直接计算value是否匹配b (value是空, 或者等于cb个b的重复)
return n == 0 or n % cb == 0 and value == cb * value[: n // cb]
if cb == 0:
# 特殊情况3: pattern中没有b, 则直接计算value是否匹配a (value是空, 或者等于ca个a的重复)
return n == 0 or n % ca == 0 and value == ca * value[: n // ca]
# 此时说明ca和cb都大于0
# 开始从0到n遍历字符串a的长度lea
for lea in range(n + 1):
if ca * lea > n:
# 当前a的总长度已经大于n了, 当前和更大的长度肯定都无效, 直接break
break
if (n - ca * lea) % cb == 0:
# 剩余部分能整除cb, 可能存在有效解, 计算得出b的长度leb
leb = (n - ca * lea) // cb
# i是当前value字符串的起始下标
i = 0
# a和b分别是pattern中a和b对应到value的字符串, 初始化为空
a, b = "", ""
for x in pattern:
if x == "a":
if a == "" or value[i : i + lea] == a:
# a尚未被定义, 或者等于现在区间, 匹配有效, 继续循环
a = value[i : i + lea]
i += lea
else:
# 否则说明遇到不匹配, 跳出循环
break
else:
if b == "" or value[i : i + leb] == b:
# b尚未被定义, 或者等于现在区间, 匹配有效, 继续循环
b = value[i : i + leb]
i += leb
else:
# 否则说明遇到不匹配, 跳出循环
break
else:
if a == b:
# 特殊情况4: a和b映射后的字符串相同, 无效
continue
# 此时说明a和b不相同, 且value匹配对应的pattern, 有效
return True
return False
大家可以在下面这些地方找到我~
我的 GitHub
我的 Leetcode
我的 CSDN
我的知乎专栏
我的头条号
我的牛客网博客
我的公众号: 算法精选, 欢迎大家扫码关注~