Loading W Code...
Master pattern matching, manipulation, and classic interview problems.
6
Topics
50
Minutes
O(N)
KMP Search
2
Visualizers
Imagine a standard C++ std::string as an expanding accordion binder that handles its own memory resizing. In contrast, C-Style strings (char[]) are like a rigid row of mailboxes where the last mailbox must contain a special red flag (\0 null terminator) to indicate that the letter sequence is complete.
In C++, character sequences can be managed using two distinct layouts:
O(1) size lookup).\0 so standard output and processing loops know where to stop scanning.#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "Hello";
int len = s.length(); // O(1) length check
string sub = s.substr(0, 2); // Extract "He"
size_t idx = s.find("ll"); // Returns index 2
if (idx != string::npos) {
cout << "Found pattern at: " << idx << endl;
}
return 0;
}Imagine folding a strip of paper in half. If the characters printed on both halves overlap and match perfectly, the word is a palindrome.
A string is a Palindrome if it reads the same forward and backward (e.g., "racecar", "madam").
left = 0 and right = n - 1.left < right:
left++ and decrement right--.#include <string>
using namespace std;
bool isPalindrome(string s) {
int l = 0;
int r = s.length() - 1;
while (l < r) {
if (s[l] != s[r]) {
return false;
}
l++;
r--;
}
return true;
}Imagine searching for a specific signature pattern in a long log book. When you hit a character mismatch, instead of flipping all the way back to the beginning of the signature, you check a bookmark index that tells you how much of the matched prefix can be reused to skip redundant checks.
The Knuth-Morris-Pratt (KMP) algorithm searches for occurrences of a pattern within a text in linear O(N + M) time.
lps[i] stores the length of the longest proper prefix of the pattern substring pat[0..i] that is also a suffix of the same substring.j in the pattern, we don't start comparing from the beginning of the pattern. Instead, we jump j back to lps[j - 1] and continue.#include <vector>
#include <string>
using namespace std;
// Generate the LPS (Longest Prefix Suffix) lookup array
vector<int> computeLPS(string& pat) {
int m = pat.size();
vector<int> lps(m, 0);
int len = 0;
int i = 1;
while (i < m) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1]; // Use prefix history
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}Imagine identifying a suspect. Instead of checking their detailed facial features character-by-character (which is slow), you check their unique fingerprint hash. Only when the hashes match do you perform a detailed visual inspection to avoid collision errors.
The Rabin-Karp algorithm uses hashing to search for a pattern in text:
O(M) time), we subtract the leaving character's value and add the entering character's value in O(1) time.#include <string>
#include <vector>
using namespace std;
// Rabin-Karp Rolling Hash Formulation
// hash(s) = (s[0]*p^(m-1) + s[1]*p^(m-2) + ... + s[m-1]*p^0) % MOD
// To shift window: newHash = (oldHash - leavingChar * p^(m-1)) * p + enteringCharImagine checking two grocery crates to see if they contain the exact same items. Instead of sorting all items, you count their frequencies. If crate A has 3 apples and 2 oranges, and crate B has 3 apples and 2 oranges, they match.
Two strings are Anagrams if they contain the same characters in the exact same frequencies (e.g., "listen" and "silent").
Instead of sorting the strings (O(N log N) time), we can count frequencies using a fixed-size integer array of size 26 (representing 'a' through 'z'):
#include <string>
#include <vector>
using namespace std;
bool isAnagram(string s, string t) {
if (s.length() != t.length()) return false;
vector<int> count(26, 0);
for (char c : s) count[c - 'a']++;
for (char c : t) count[c - 'a']--;
for (int val : count) {
if (val != 0) return false;
}
return true;
}The Z-Algorithm constructs a helper array Z where Z[i] represents the length of the longest substring starting at index i that matches the prefix of the string.
To search for a pattern P in a text T:
S = P + "$" + T.S.i where Z[i] equals the length of P marks the start of a match.#include <vector>
#include <string>
#include <algorithm>
using namespace std;
vector<int> z_function(string s) {
int n = s.length();
vector<int> z(n, 0);
int l = 0, r = 0;
for (int i = 1; i < n; i++) {
if (i <= r) {
z[i] = min(r - i + 1, z[i - l]);
}
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
z[i]++;
}
if (i + z[i] - 1 > r) {
l = i;
r = i + z[i] - 1;
}
}
return z;
}