Skip to content

Commit dfcb983

Browse files
committed
Add README to 567 Permutation in String
1 parent 250b477 commit dfcb983

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Permutation in String
2+
3+
## Problem Description
4+
5+
Given two strings `s1` and `s2`, return `true` if `s2` contains a permutation of `s1`,
6+
or `false` otherwise.
7+
8+
In other words, return `true` if one of `s1`'s permutations is the substring of `s2`.
9+
10+
**Example 1:**
11+
12+
* Input: `s1 = "ab", s2 = "eidbaooo"`
13+
* Output: `true`
14+
* Explanation: `s2` contains one permutation of `s1` (`"ba"`).
15+
16+
**Example 2:**
17+
18+
* Input: `s1 = "ab", s2 = "eidboaoo"`
19+
* Output: `false`
20+
21+
**Constraints:**
22+
23+
* `1 <= s1.length, s2.length <= 10^4`
24+
* `s1` and `s2` consist of lowercase English letters.
25+
26+
## Solution
27+
28+
```python
29+
def check_inclusion(s1: str, s2: str) -> bool:
30+
"""
31+
Check if any permutation of s1 exists as a substring in s2.
32+
33+
This function uses a sliding window approach with hash maps to efficiently
34+
track character counts and determine if any permutation of s1 is present in s2.
35+
36+
:param s1: The string whose permutations we want to find in s2.
37+
:param s2: The string in which we're searching for permutations of s1.
38+
:return: True if any permutation of s1 is found as a substring in s2, False otherwise.
39+
"""
40+
pattern_hash = {}
41+
for character in s1:
42+
if character not in pattern_hash:
43+
pattern_hash[character] = 1
44+
else:
45+
pattern_hash[character] += 1
46+
47+
hash_copy = pattern_hash.copy()
48+
pattern_length = len(s1)
49+
50+
for index in range(len(s2)):
51+
if index >= pattern_length:
52+
outgoing_character = s2[index - pattern_length]
53+
if outgoing_character in pattern_hash:
54+
if outgoing_character not in hash_copy:
55+
hash_copy[outgoing_character] = 1
56+
else:
57+
hash_copy[outgoing_character] += 1
58+
if hash_copy[outgoing_character] == 0:
59+
del hash_copy[outgoing_character]
60+
61+
incoming_character = s2[index]
62+
if incoming_character in pattern_hash:
63+
if incoming_character in hash_copy:
64+
hash_copy[incoming_character] -= 1
65+
else:
66+
hash_copy[incoming_character] = -1
67+
if hash_copy[incoming_character] == 0:
68+
del hash_copy[incoming_character]
69+
if len(hash_copy) == 0:
70+
return True
71+
return False
72+
```
73+
74+
* **Time Complexity:** $O(n)$
75+
* **Space Complexity:** $O(1)$
76+
77+
## Explanation of the Solution
78+
79+
The problem reduces to finding a window in `s2` where the character frequency exactly matches that of `s1`
80+
(regardless of order). This is equivalent to checking for an anagram of `s1` in `s2`.
81+
82+
1. Frequency Map for s1 (pattern_hash)
83+
* Create a hash map counting occurrences of each character in `s1`.
84+
2. Sliding Window over s2
85+
* Traverse `s2` while maintaining a dynamically adjusted window of size `len(s1)`.
86+
* Use a copy of `pattern_hash` (`hash_copy`) to track how much the current window deviates from `s1`'s frequencies.
87+
* Goal: `hash_copy` becomes empty when the window matches `s1`'s frequencies.
88+
3. Window Adjustment Logic
89+
* For each new character (incoming_character):
90+
* If it exists in `pattern_hash`, decrement its count in `hash_copy`.
91+
* If a count reaches 0, remove the key (indicates balance with `s1`).
92+
* For the character exiting the window (outgoing_character):
93+
* Re-increment its count in `hash_copy` (reversing the earlier decrement).
94+
* Remove the key if the count rebalances to 0.
95+
4. Check for Permutation
96+
* If `hash_copy` is ever empty, the current window is a permutation of `s1` → return `True`.
97+
* If the loop ends without finding such a window → return `False`.

sliding-window/567_Permutation_in_String/solution.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
def check_inclusion(s1: str, s2: str) -> bool:
2+
"""
3+
Check if any permutation of s1 exists as a substring in s2.
4+
5+
This function uses a sliding window approach with hash maps to efficiently
6+
track character counts and determine if any permutation of s1 is present in s2.
7+
8+
:param s1: The string whose permutations we want to find in s2.
9+
:param s2: The string in which we're searching for permutations of s1.
10+
:return: True if any permutation of s1 is found as a substring in s2, False otherwise.
11+
"""
212
pattern_hash = {}
313
for character in s1:
414
if character not in pattern_hash:

0 commit comments

Comments
 (0)