Lovers Arcana: Edit Distance & Subset Sum
Tags: #◇CSALGCM #◇Problem Sets #◇HackerRank #◇Algorithms #◇Dynamic Programming
◇Overview
The Lovers Arcana covers structural alignment and combinatorial decision problems: Edit Distance (Levenshtein Distance) and the Subset Sum / Partition Problem.
◇Problem 1: Edit Distance (Levenshtein Distance)
Problem Description
Given two strings of length and of length , determine the minimum number of single-character edit operations required to convert string into string . The allowed operations are:
- Insert a character.
- Delete a character.
- Replace a character.
Constraints:
- Strings consist of lowercase English letters.
Approach & Intuition
Let denote the minimum edit distance between prefixes and .
- Base cases:
- : Converting to empty string requires deletions.
- : Converting empty string to requires insertions.
- Inductive Step:
- If : No new operation needed; .
- If : Choose the minimum among:
- Delete :
- Insert :
- Replace with :
Mathematical Recurrence
Stepped Calculation Trace
Let () and ():
Tabulation Matrix:
| r | o | s | ||
|---|---|---|---|---|
| 0 | 1 | 2 | 3 | |
| h | 1 | 1 | 2 | 3 |
| o | 2 | 2 | 1 | 2 |
| r | 3 | 2 | 2 | 2 |
| s | 4 | 3 | 3 | 2 |
| e | 5 | 4 | 4 | 3 |
Optimal Operation Traceback:
- ['e' 's']: Minimum neighbor is Delete 'e' (Cost +1).
- ['s' = 's']: Diagonal Match! (Cost +0).
- ['r' 'o']: Minimum neighbor is Delete 'r' (Cost +1).
- ['o' = 'o']: Diagonal Match! (Cost +0).
- ['h' 'r']: Diagonal Replace 'h' with 'r' (Cost +1).
- Total Operations: 3 (Replace 'h' 'r', Delete 'r', Delete 'e').
◇Problem 2: The Subset Sum Problem
Problem Description
Given a multiset of non-negative integers and a target integer sum . Determine whether there exists a non-empty subset of whose elements sum up to exactly .
Constraints:
Approach & Intuition: Boolean State Space
Let be a boolean flag indicating whether a sum of can be formed using a subset of the first elements.
For element :
Base case: (the empty subset achieves sum 0). All other .
Stepped Calculation Trace
Let and :
- Init:
- Include : Sums formed:
- Include : Sums formed: immediately!
- The subset is , yielding .
◇Complete C++ Implementation
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// Problem 1: Edit Distance
int minEditDistance(const string& A, const string& B) {
int m = A.size();
int n = B.size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (int i = 0; i <= m; i++) dp[i][0] = i;
for (int j = 0; j <= n; j++) dp[0][j] = j;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (A[i - 1] == B[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = 1 + min({dp[i - 1][j], // Deletion
dp[i][j - 1], // Insertion
dp[i - 1][j - 1] // Substitution
});
}
}
}
return dp[m][n];
}
// Problem 2: 1D Space-Optimized Subset Sum
bool canPartitionSubsetSum(const vector<int>& S, int target) {
vector<bool> dp(target + 1, false);
dp[0] = true; // Base case: Sum 0 is always achievable
for (int num : S) {
// Traverse backwards to use each number at most once
for (int t = target; t >= num; t--) {
if (dp[t - num]) {
dp[t] = true;
}
}
}
return dp[target];
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Test Edit Distance
string word1 = "horse";
string word2 = "ros";
cout << "Min Edit Distance ('horse' -> 'ros'): "
<< minEditDistance(word1, word2) << "\n"; // Output: 3
// Test Subset Sum
vector<int> nums = {3, 34, 4, 12, 5, 2};
int target = 9;
cout << "Subset sum for target 9 exists: "
<< (canPartitionSubsetSum(nums, target) ? "Yes" : "No") << "\n"; // Output: Yes (4 + 5)
return 0;
}
◇References & Navigation
- Previous Topic: ◇[PS] Hierophant Arcana
- Next Topic: ◇[PS] Chariot Arcana
- Related Notes: ◇Dynamic Programming Introduction