71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
|
class Solution:
|
||
|
def checkInclusion(self, s1: str, s2: str) -> bool:
|
||
|
'''
|
||
|
Sliding window, better space utilization
|
||
|
'''
|
||
|
|
||
|
if len(s1) > len(s2): return False
|
||
|
|
||
|
def get_letter_index(letter):
|
||
|
'''
|
||
|
Problem only concerns with lowercase letters
|
||
|
'''
|
||
|
return ord(letter) - ord('a')
|
||
|
|
||
|
|
||
|
s1_count, s2_count = [0] * 26, [0] * 26
|
||
|
for i in range(len(s1)):
|
||
|
s1_count[get_letter_index(s1[i])] += 1
|
||
|
s2_count[get_letter_index(s2[i])] += 1
|
||
|
|
||
|
# Keep a `count_matches` variable that tells us how many
|
||
|
# counts of a-z from s1 match a-z in the window of s2
|
||
|
count_matches = 0
|
||
|
|
||
|
for i in range(26):
|
||
|
if s1_count[i] == s2_count[i]:
|
||
|
count_matches += 1
|
||
|
|
||
|
# It's possible that we get a perfect match right after the
|
||
|
# above initial computation. If yes, yay!
|
||
|
if count_matches == 26:
|
||
|
return True
|
||
|
|
||
|
|
||
|
# Start from the very next character after figuring out the
|
||
|
# initial `count_matches` value which would be at len(s1)
|
||
|
l = 0
|
||
|
for r in range(len(s1), len(s2)):
|
||
|
#
|
||
|
# Adding rightmost letter
|
||
|
#
|
||
|
li = get_letter_index(s2[r])
|
||
|
s2_count[li] += 1
|
||
|
|
||
|
if s1_count[li] == s2_count[li]:
|
||
|
count_matches += 1
|
||
|
# If after adding new right letter, count increased by 1 for
|
||
|
# the letter index, then that means total matches also reduced
|
||
|
# by 1
|
||
|
elif s1_count[li] + 1 == s2_count[li]:
|
||
|
count_matches -= 1
|
||
|
|
||
|
#
|
||
|
# Removing leftmost letter
|
||
|
#
|
||
|
li = get_letter_index(s2[l])
|
||
|
s2_count[li] -= 1
|
||
|
|
||
|
if s1_count[li] == s2_count[li]:
|
||
|
count_matches += 1
|
||
|
# If after removing leftmost letter, count decreased by 1, then
|
||
|
# our total matches also reduced by 1
|
||
|
elif s1_count[li] - 1 == s2_count[li]:
|
||
|
count_matches -= 1
|
||
|
|
||
|
if count_matches == 26: return True
|
||
|
|
||
|
l += 1
|
||
|
|
||
|
return count_matches == 26
|