KMP Pattern Matching Algorithm in DSA C++ - Time & Space Complexity
We want to understand how fast the KMP algorithm finds a pattern inside a text.
Specifically, how the work grows as the text and pattern get longer.
Analyze the time complexity of the following KMP code snippet.
void computeLPSArray(string pat, int M, int* lps) {
int len = 0, i = 1;
lps[0] = 0;
while (i < M) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) len = lps[len - 1];
else {
lps[i] = 0;
i++;
}
}
}
}
void KMPSearch(string pat, string txt) {
int M = pat.length(), N = txt.length();
int lps[M];
computeLPSArray(pat, M, lps);
int i = 0, j = 0;
while (i < N) {
if (pat[j] == txt[i]) {
i++; j++;
}
if (j == M) {
j = lps[j - 1];
} else if (i < N && pat[j] != txt[i]) {
if (j != 0) j = lps[j - 1];
else i++;
}
}
}
This code builds a helper array and then searches the pattern in the text efficiently.
Look for loops and repeated steps.
- Primary operation: The while loops in
computeLPSArrayandKMPSearchthat scan the pattern and text. - How many times: Each loop runs at most once per character in pattern or text, no backtracking over characters.
As the pattern length (M) and text length (N) grow, the operations grow roughly in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| Pattern M=10, Text N=10 | About 20 steps |
| Pattern M=100, Text N=100 | About 200 steps |
| Pattern M=1000, Text N=1000 | About 2000 steps |
Pattern observation: The work grows linearly with both pattern and text size combined.
Time Complexity: O(N + M)
This means the algorithm checks each character in the text and pattern only once, making it very efficient.
[X] Wrong: "KMP is slower because it uses extra loops and backtracking."
[OK] Correct: The extra steps actually avoid repeating work, so the total steps stay linear, not quadratic.
Understanding KMP's time complexity shows you can analyze efficient algorithms that avoid repeated work, a key skill in coding interviews.
"What if the pattern was very long but the text was very short? How would the time complexity change?"
Practice
Solution
Step 1: Understand KMP's goal
KMP algorithm is designed to search for a pattern inside a text efficiently.Step 2: Identify how it works
It avoids rechecking characters by using a prefix table to skip unnecessary comparisons.Final Answer:
To find occurrences of a pattern in a text efficiently without rechecking characters -> Option AQuick Check:
KMP purpose = efficient pattern search [OK]
- Thinking KMP sorts or modifies the text
- Confusing KMP with simple substring search
- Assuming KMP counts characters or vowels
Solution
Step 1: Understand dynamic array allocation in C++
To create an array dynamically, use pointer with new keyword: int* lps = new int[size];Step 2: Check options
int* lps = new int[pattern_length]; correctly uses pointer and new to allocate array of given length.Final Answer:
int* lps = new int[pattern_length]; -> Option BQuick Check:
Dynamic array = int* lps = new int[size]; [OK]
- Using int lps = new int[] (wrong type)
- Declaring fixed size without initialization
- Incorrect array syntax like int lps[] = size
std::string text = "ababcabcabababd"; std::string pattern = "ababd"; std::vector<int> result = kmpSearch(text, pattern); for(int pos : result) std::cout << pos << " ";
Assuming
kmpSearch returns all starting indices of pattern in text.Solution
Step 1: Identify pattern occurrences in text
Check where "ababd" appears in "ababcabcabababd". It appears starting at index 10 only.Step 2: Confirm output format
kmpSearch returns vector of indices; printing them separated by space outputs "10 ".Final Answer:
10 -> Option AQuick Check:
Pattern found at index 10 only [OK]
- Assuming multiple matches without checking text
- Confusing substring indices
- Printing no output if pattern not found
void computeLPSArray(string pat, int M, int* lps) {
int len = 0;
lps[0] = 0;
int i = 1;
while (i < M) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len]; // Bug here
} else {
lps[i] = 0;
i++;
}
}
}
}What is the bug and how to fix it?
Solution
Step 1: Identify incorrect index in LPS update
When mismatch occurs and len != 0, len should be updated to lps[len-1], not lps[len].Step 2: Correct the assignment
Change len = lps[len]; to len = lps[len - 1]; to avoid out-of-bound and logical error.Final Answer:
Change len = lps[len]; to len = lps[len - 1]; -> Option DQuick Check:
LPS update uses len-1 index [OK]
- Using len index directly causes wrong LPS values
- Changing loop type unnecessarily
- Removing else block breaks logic
Solution
Step 1: Understand KMP's limitation
KMP efficiently finds one pattern in text but running it repeatedly for many patterns is inefficient.Step 2: Identify better multi-pattern method
Building a trie and using Aho-Corasick algorithm finds all patterns simultaneously efficiently.Final Answer:
Build a trie of patterns and run Aho-Corasick algorithm -> Option CQuick Check:
Multi-pattern search = Aho-Corasick [OK]
- Running KMP repeatedly wastes time
- Concatenating patterns confuses matching
- Ignoring specialized multi-pattern algorithms
Ready to prove it?
Pass the test and this pattern moves unknown
