You are given a string s
and a pattern string p
, where p
contains exactly one '*'
character.
The '*'
in p
can be replaced with any sequence of zero or more characters.
Return true
if p
can be made a substring of s
, and false
otherwise.
Example 1:
s = "leetcode", p = "ee*e"
true
'*'
with "tcod"
, the substring "eetcode"
matches the pattern.Example 2:
s = "car", p = "c*v"
false
Example 3:
s = "luck", p = "u*"
true
"u"
, "uc"
, and "uck"
match the pattern.Constraints:
1 <= s.length <= 50
1 <= p.length <= 50
s
contains only lowercase English letters.p
contains only lowercase English letters and exactly one '*'
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 approach to substring matching involves checking every possible alignment of the pattern within the text. We'll systematically slide the pattern across the text and compare them character by character. If a match is found at any position, we'll report it.
Here's how the algorithm would work step-by-step:
def substring_matching_brute_force(text, pattern):
matches = []
text_length = len(text)
pattern_length = len(pattern)
for text_index in range(text_length - pattern_length + 1):
# Iterate through possible starting positions of pattern in text
pattern_index = 0
while (pattern_index < pattern_length and
text[text_index + pattern_index] == pattern[pattern_index]):
pattern_index += 1
# If pattern_index reaches pattern_length, all chars matched.
if pattern_index == pattern_length:
matches.append(text_index)
return matches
The best way to solve this problem involves transforming the pattern into a simplified representation that helps us quickly compare it against the text. Instead of directly comparing the pattern, we'll focus on finding repeated relationships within it, and apply that logic when scanning the text.
Here's how the algorithm would work step-by-step:
def substring_match_pattern(text, pattern):
pattern_length = len(pattern)
text_length = len(text)
results = []
def encode_string(input_string):
encoding_map = {}
next_code = 1
encoded_string = ''
for char in input_string:
if char not in encoding_map:
encoding_map[char] = str(next_code)
next_code += 1
encoded_string += encoding_map[char]
return encoded_string
encoded_pattern = encode_string(pattern)
# Iterate through the text to find potential matches.
for i in range(text_length - pattern_length + 1):
substring = text[i:i + pattern_length]
encoded_substring = encode_string(substring)
# Compare the encoded pattern and substring.
if encoded_pattern == encoded_substring:
results.append(i)
return results
# Example Usage
# text = "redblueredblue"
# pattern = "redblue"
# print(substring_match_pattern(text, pattern))
# text = "abcabcabc"
# pattern = "abc"
# print(substring_match_pattern(text, pattern))
# text = "ababababab"
# pattern = "aba"
# print(substring_match_pattern(text, pattern))
# text = "aabbabbaab"
# pattern = "aabb"
# print(substring_match_pattern(text, pattern))
def test_cases():
assert substring_match_pattern("redblueredblue", "redblue") == [0, 6]
assert substring_match_pattern("abcabcabc", "abc") == [0, 3, 6]
assert substring_match_pattern("ababababab", "aba") == [0, 2, 4, 6]
assert substring_match_pattern("aabbabbaab", "aabb") == [0, 4]
assert substring_match_pattern("aabbabbaab", "abba") == [2, 5]
assert substring_match_pattern("aabbabbaab", "bba") == [3, 6]
assert substring_match_pattern("aabbabbaab", "b") == [2, 3, 5, 6, 8]
assert substring_match_pattern("aabbabbaab", "a") == [0, 1, 4, 7, 9]
assert substring_match_pattern("aabbabbaab", "") == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
assert substring_match_pattern("", "") == [0]
# Test case with no match
assert substring_match_pattern("abcdefg", "xyz") == []
# Test case where pattern is longer than text
assert substring_match_pattern("abc", "abcdef") == []
print("All test cases passed!")
#test_cases()
Case | How to Handle |
---|---|
Empty pattern string | Return an empty list since no match is possible with an empty pattern. |
Empty text string | Return an empty list as the pattern cannot be found in an empty text. |
Null pattern string | Throw an IllegalArgumentException or return an error code to indicate invalid input. |
Null text string | Throw an IllegalArgumentException or return an error code to indicate invalid input. |
Pattern string longer than text string | Return an empty list since the pattern cannot be contained within the text string. |
Pattern containing special characters (e.g., regex metacharacters) | Escape special characters in the pattern string before using it in any string matching function. |
Text string contains Unicode characters | Ensure the string matching algorithm correctly handles Unicode characters based on the encoding used. |
Pattern and Text strings are identical | Return a list containing index 0 since the pattern starts at the very beginning of the text. |