Dadas dos cadenas s1 y s2, escriba una función para determinar si s2 contiene la permutación de s1. En otras palabras, una de las permutaciones de la primera cadena es una subcadena de la segunda cadena.
Ejemplo 1: Entrada: s1 = "ab" s2 = "eidbaooo" Salida: Verdadero
Explicación: s2 contiene una de las permutaciones de s1 ("ba").
Ejemplo 2: Entrada: s1 = "ab" s2 = "eidboaoo" Salida: FalsoFuente: LeetCode
Enlace: https://leetcode-cn.com/problems/permutation-in-string
Esta pregunta es muy similar a la solución de " 438. Encuentra todas las letras de dislexia en una cadena "
Método 1: use la ventana deslizante para comparar los caracteres en la ventana deslizante con la cadena en s1, si son iguales, se considera
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
if len(s1)>len(s2): return False
record=Counter(s1)
length=len(s1)
win={}
l=0
rst=False # 不同处
for r,c in enumerate(s2):
if c not in record.keys():
win.clear()
l=r+1
else:
win[c]=win.get(c,0)+1
if r-l+1==length:
if win==record:
rst=True # 不同处
win[s2[l]]-=1
l+=1
return rst
Método 2: una variante del método 1
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
if len(s1) > len(s2):
return False
need = {}
window = {}
for i in s1:
if i in need:
need[i] += 1
else:
need[i] = 1
print(need,len(need))
left = 0
right = 0
valid = 0
while right < len(s2):
c = s2[right]
right += 1
if c in need:
# 窗口开始,在不在need和window中
if c in window:
window[c] += 1
else:
window[c] = 1
# 判断窗口函数值是否相同,相同则标记加1
if window[c] == need[c]:
valid += 1
if right - left >= len(s1):
# 当窗口长度大于目标字符串长度时
# 若valid等于字典need的长度时,即所有字符都比对完成时,还回 true
if valid == len(need):
return True
# 移动左边界,把最左边的字符清除出window
d = s2[left]
left += 1
if d in need:
# 如果这时需要清除的字符d在字典need中,则需要处理标记值valid和窗口值
if window[d] == need[d]:
valid -= 1
window[d] -= 1
return False