-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpermutation_in_strings.py
68 lines (57 loc) · 2.93 KB
/
permutation_in_strings.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
'''
Question: https://leetcode.com/problems/permutation-in-string/
'''
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
'''
Use a sliding window to compare the count of the characters in each string.
Time Complexity = O(26) + O(n) = O(n)
'''
# Length of `s1` needs to be less than length of `s2`
if len(s1) > len(s2):
return False
# Counters for the characters in each string
s1Count, s2Count = [0]*26, [0]*26
# Populate the character count arrays - only need to do it for the length of `s1`
for i in range(len(s1)):
# Get the index of the character in the `count` array
s1Count[ord(s1[i]) - ord('a')] += 1
s2Count[ord(s2[i]) - ord('a')] += 1
# Now check the number of matches of characters in `s1Count` and `s2Count`
matches = 0
for i in range(26):
if s1Count[i] == s2Count[i]:
matches += 1
# Now, sliding window over the remaining characters of `s2` to find the permutation string
# Sliding window implemented using two pointers (left at 0 and right moves from 0 to end)
# Note: window start at len(s1), since we already checked the characters
# from 0 to len(s1) - 1 in the previous (initial) window
l = 0
for r in range(len(s1), len(s2)):
# Return if the current window is a perfect match between `s1` and permutation in `s2`
if matches == 26:
return True
## Add the right character (at index `r`) into the window and update the `matches` counter
index = ord(s2[r]) - ord('a')
s2Count[index] += 1
# If adding the character makes the count in both counters equal, increment `matches`
if s1Count[index] == s2Count[index]:
matches += 1
# But if adding the character makes the count in s1Count one less than s2Count,
# then we created a mismatch, so decrement `matches`
elif s1Count[index] + 1 == s2Count[index]:
matches -= 1
## Same operation for left character, but here we are removing a character (since the sliding window moves to the right)
index = ord(s2[l]) - ord('a')
s2Count[index] -= 1
# Same condition check as done for left character
if s1Count[index] == s2Count[index]:
matches += 1
# Here, if removing the left character, made the s1Count of the index one less than s2Count
# we created a mismatch, so we decrement `matches`
elif s1Count[index] - 1 == s2Count[index]:
matches -= 1
# Remember to update the left pointer!
l += 1
# Finally, check if the matches are 26, then permutation exists, else doesn't!
return True if matches == 26 else False