leetcode/0567_permutation-in-string/python3/solution.py

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