Substring Search Patterns in DSA Rust - Time & Space Complexity
We want to understand how long it takes to find a smaller string inside a bigger one.
How does the search time change when the strings get longer?
Analyze the time complexity of the following code snippet.
fn contains_substring(text: &str, pattern: &str) -> bool {
let n = text.len();
let m = pattern.len();
if m > n {
return false;
}
for i in 0..=n - m {
if &text[i..i + m] == pattern {
return true;
}
}
false
}
This code checks if the pattern appears anywhere inside the text by comparing slices one by one.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Comparing the pattern with a slice of the text.
- How many times: Up to (n - m + 1) times, where n is text length and m is pattern length.
Each position in the text is checked by comparing up to m characters.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 (text), 3 (pattern) | ~8 * 3 = 24 comparisons |
| 100 (text), 5 (pattern) | ~96 * 5 = 480 comparisons |
| 1000 (text), 10 (pattern) | ~991 * 10 = 9,910 comparisons |
Pattern observation: The work grows roughly by multiplying text length by pattern length.
Time Complexity: O(n * m)
This means the time to search grows proportionally to the product of text and pattern lengths.
[X] Wrong: "The search always takes time proportional to the text length only."
[OK] Correct: Because each position requires checking the whole pattern, so pattern length matters too.
Understanding this helps you explain why simple substring search can be slow and why smarter methods exist.
"What if we used a smarter algorithm like KMP? How would the time complexity change?"
Practice
Solution
Step 1: Understand substring search goal
Substring search algorithms check if a smaller string (pattern) appears inside a bigger string (text).Step 2: Compare with other string operations
Sorting, reversing, and counting characters are different operations unrelated to searching for a substring.Final Answer:
To find if a smaller string exists inside a larger string -> Option AQuick Check:
Substring search = find smaller string inside bigger string [OK]
- Confusing substring search with sorting or reversing strings
- Thinking substring search counts characters
- Mixing substring search with string length calculation
needle is a substring of haystack?Solution
Step 1: Identify correct Rust substring method
Rust's standard library providescontainsmethod on strings to check substring presence, returning a boolean.Step 2: Check other options for syntax errors
findreturns an Option, not a boolean;inis not a Rust keyword;index_ofdoes not exist in Rust standard strings.Final Answer:
if haystack.contains(needle) { println!("Found"); } -> Option DQuick Check:
Rust substring check uses contains() [OK]
- Using .find() as a boolean without checking Option
- Trying Python or other language syntax like 'in'
- Using non-existent methods like index_of
let text = "hello world";
let pattern = "wor";
if text.contains(pattern) {
println!("Pattern found");
} else {
println!("Pattern not found");
}Solution
Step 1: Check if pattern is substring of text
The string "hello world" contains "wor" starting at index 6.Step 2: Evaluate the if condition
Sincetext.contains(pattern)returns true, the code prints "Pattern found".Final Answer:
Pattern found -> Option BQuick Check:
"hello world" contains "wor" = true [OK]
- Assuming contains() checks for whole words only
- Confusing contains() with starts_with() or ends_with()
- Expecting compilation or runtime errors without syntax issues
let text = "rustacean";
let pattern = "ace";
if text.find(pattern) {
println!("Found");
} else {
println!("Not found");
}Solution
Step 1: Understand return type of find()
In Rust,find()returns an Option<usize>, not a boolean.Step 2: Check if condition usage
The if condition expects a boolean, buttext.find(pattern)returns Option, causing a type mismatch error.Final Answer:
Using find() without handling Option result -> Option CQuick Check:
find() returns Option, not bool [OK]
- Treating find() as boolean directly in if
- Ignoring Option type returned by find()
- Confusing contains() and find() return types
Solution
Step 1: Analyze naive approach inefficiency
Checking each pattern separately in a large text is slow because it repeats scanning multiple times.Step 2: Understand advanced multi-pattern search
Trie-based algorithms like Aho-Corasick build a structure to search all patterns at once efficiently.Step 3: Evaluate other options
Sorting and binary searching patterns is not suitable for substring search; reversing strings does not help search efficiency.Final Answer:
Using a Trie or Aho-Corasick algorithm to search all patterns simultaneously -> Option AQuick Check:
Multi-pattern search uses Trie/Aho-Corasick [OK]
- Using naive repeated searches for many patterns
- Trying sorting-based methods for substring search
- Thinking reversing strings improves search speed
Ready to prove it?
Pass the test and this pattern moves unknown
