Given two strings s1
and s2
, return true
if s2
contains a permutation of s1
, or false
otherwise.
In other words, return true
if one of s1
's permutations is the substring of s2
.
Example 1:
Input: s1 = "ab", s2 = "eidbaooo" Output: true Explanation: s2 contains one permutation of s1 ("ba").
Example 2:
Input: s1 = "ab", s2 = "eidboaoo" Output: false
Constraints:
1 <= s1.length, s2.length <= 104
s1
and s2
consist of lowercase English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem is about checking every possible arrangement. We will try every possible rearrangement of the shorter string to see if it is contained within the larger string. This involves creating and comparing a large number of possibilities.
Here's how the algorithm would work step-by-step:
def permutation_in_string_brute_force(short_string, long_string):
from itertools import permutations
# Generate all possible permutations of the short string
all_permutations = [''.join(permutation) for permutation in permutations(short_string)]
# Iterate through the long string with a sliding window
for index in range(len(long_string) - len(short_string) + 1):
substring_to_check = long_string[index:index + len(short_string)]
# Iterate through all the permutations of the short string
for possible_permutation in all_permutations:
# Check if a permutation is a match to the current substring
if substring_to_check == possible_permutation:
# If match found, return true
return True
# If no permutation matches any substring, return false
return False
The trick is to avoid generating all possible arrangements. Instead, we focus on checking if the characters in the smaller string are present in a sliding window of the larger string, and if those characters appear with the correct frequency.
Here's how the algorithm would work step-by-step:
def find_permutation(smaller_string, larger_string):
smaller_string_length = len(smaller_string)
larger_string_length = len(larger_string)
if smaller_string_length > larger_string_length:
return False
# Store char frequencies of the smaller string
smaller_string_char_counts = {}
for character in smaller_string:
smaller_string_char_counts[character] = smaller_string_char_counts.get(character, 0) + 1
# Initialize the sliding window's char counts
window_char_counts = {}
for i in range(smaller_string_length):
character = larger_string[i]
window_char_counts[character] = window_char_counts.get(character, 0) + 1
# Check if the initial window is a permutation
if window_char_counts == smaller_string_char_counts:
return True
# Slide the window across the larger string
for i in range(1, larger_string_length - smaller_string_length + 1):
# Remove the leftmost character from the window
left_character = larger_string[i - 1]
window_char_counts[left_character] -= 1
if window_char_counts[left_character] == 0:
del window_char_counts[left_character]
# Add the rightmost character to the window
right_character = larger_string[i + smaller_string_length - 1]
window_char_counts[right_character] = window_char_counts.get(right_character, 0) + 1
# Compare the current window with the smaller string
if window_char_counts == smaller_string_char_counts:
# Permutation found
return True
# No permutation found
return False
Case | How to Handle |
---|---|
s1 or s2 is null or empty | Return false if either s1 or s2 is null or empty as a permutation cannot exist. |
s1 is longer than s2 | Return false if s1 is longer than s2, as s2 cannot contain a permutation of s1. |
s1 and s2 are identical | Return true if s1 and s2 are identical, as s2 trivially contains a permutation of s1. |
s1 and s2 contain only one character | Compare the characters directly and return true if they match, false otherwise. |
s1 contains duplicate characters | The sliding window and character frequency map approach will accurately account for duplicates. |
s2 contains many repeating characters, but not a permutation of s1 | The frequency map comparison will not find a match and correctly return false. |
Maximum length strings with Unicode characters | Ensure the chosen frequency map representation (e.g., hash map) can handle the Unicode character range and doesn't overflow, while considering time complexity constraints for very large inputs. |
s1 is very long and contains many distinct characters, compared to a short s2 | The initial frequency map calculation of s1 might be expensive, but the sliding window should efficiently compare it with s2's substrings. |