String Matching Algorithms
String Matching Algorithms
Simple but inefficient: O(m * n) time complexity (m = pattern length, n = text length).
3. Rabin-Karp Algorithm
4. Boyer-Moore Algorithm
Uses bad character and good suffix heuristics to skip sections of text.
5. Aho-Corasick Algorithm
python
CopyEdit
def compute_lps(pattern):
length = 0
i=1
if pattern[i] == pattern[length]:
length += 1
lps[i] = length
i += 1
else:
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
return lps
Classical Problems
Classical Problems
2. Greedy Problems
Fractional Knapsack
3. Dynamic Programming
Fibonacci Numbers
4. Graph Problems
Topological Sorting
5. Backtracking
N-Queens Problem
Sudoku Solver
Hamiltonian Path
6. Mathematical Problems
Modular Exponentiation
7. String Problems
Anagram Detection
8. Others
Tower of Hanoi
Convex Hull (Computational Geometry)
LCS
Problem:
Given two sequences (strings or arrays), find the length of their Longest Common Subsequence — a
subsequence that appears in the same relative order (not necessarily contiguous) in both sequences.
🔎 Example:
makefile
CopyEdit
X = "ABCBDAB"
Y = "BDCAB"
Length = 4
1. Create a 2D table dp where dp[i][j] represents the length of LCS of X[0..i-1] and Y[0..j-1].
CopyEdit
dp[i][j] = 1 + dp[i-1][j-1]
3. Otherwise:
lua
CopyEdit
python
CopyEdit
m, n = len(X), len(Y)
else:
return dp[m][n]
# Example usage
X = "ABCBDAB"
Y = "BDCAB"
python
CopyEdit
m, n = len(X), len(Y)
# Backtracking
i, j = m, n
lcs_str = []
lcs_str.append(X[i - 1])
i -= 1
j -= 1
i -= 1
else:
j -= 1
return ''.join(reversed(lcs_str))
Time: O(m * n)
Problem:
Given an array of numbers, find the length of the Longest Increasing Subsequence — a subsequence
where elements are strictly increasing, but not necessarily contiguous.
🔎 Example:
mathematica
CopyEdit
Input: [10, 9, 2, 5, 3, 7, 101, 18]
Length = 4
Answer is max(dp).
📝 Code (O(n²)):
python
CopyEdit
def length_of_lis(arr):
n = len(arr)
for j in range(i):
return max(dp)
# Example
print(length_of_lis(arr)) # Output: 4
python
CopyEdit
import bisect
def length_of_lis(arr):
sub = []
for x in arr:
if i == len(sub):
sub.append(x)
else:
sub[i] = x
return len(sub)
# Example
print(length_of_lis(arr)) # Output: 4
⏳ Complexity
DP approach: O(n²)
1. Insert
2. Delete
3. Replace
🔎 Example:
text
CopyEdit
word1 = "kitten"
word2 = "sitting"
Operations:
✅ Recurrence:
If characters match:
CopyEdit
dp[i][j] = dp[i-1][j-1]
python
CopyEdit
dp[i][j] = 1 + min(
dp[i-1][j], # delete
dp[i][j-1], # insert
dp[i-1][j-1] # replace
📝 Python Code:
python
CopyEdit
m, n = len(word1), len(word2)
for i in range(m+1):
dp[i][0] = i # Deletion
for j in range(n+1):
dp[0][j] = j # Insertion
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = 1 + min(
dp[i-1][j], # delete
dp[i][j-1], # insert
dp[i-1][j-1] # replace
return dp[m][n]
# Example
Time: O(m * n)
Applications
Spell checkers
Problem:
Given an array of integers, find the contiguous subarray (containing at least one number) which has
the largest sum.
🔎 Example:
text
CopyEdit
Output: 6
Idea:
📝 Code (Python):
python
CopyEdit
def max_subarray_sum(arr):
max_sum = float('-inf')
current_sum = 0
return max_sum
# Example
print(max_subarray_sum(arr)) # Output: 6
python
CopyEdit
def max_subarray_with_indices(arr):
max_sum = float('-inf')
current_sum = 0
start = end = s = 0
for i in range(len(arr)):
current_sum += arr[i]
max_sum = current_sum
start = s
end = i
if current_sum < 0:
current_sum = 0
s=i+1
print(max_subarray_with_indices(arr))
Time: O(n)
Space: O(1)
📌 Variants