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