Question:
Given two strings S and T, determine if they are both one edit distance apart.
Hint:
1. If | n – m | is greater than 1, we know immediately both are not one-edit distance apart.
2. It might help if you consider these cases separately, m == n and m ≠ n.
3. Assume that m is always ≤ n, which greatly simplifies the conditional statements.
If m > n, we could just simply swap S and T.
4. If m == n, it becomes finding if there is exactly one modified operation. If m ≠ n, you do not have to consider the delete operation. Just consider the insert operation in T.
Solution:
O(n) runtime, O(1) space – Simple one-pass:
For the case where m is equal to n, it becomes finding if there is exactly one modified
character.
Now let’s assume m ≤ n. (If m > n we could just swap them).
Assume X represents the one-edit character. There are three one-edit distance operations
that could be applied to S.
i. Modify operation – Modify a character to X in S.
S = “abcde” T = “abXde”
ii. Insert operation – X was inserted before a character in S.
S = “abcde” T = “abcXde”
iii. Append operation – X was appended at the end of S.
S = “abcde” T = “abcdeX”
First pass over S and T concurrently and stop at the first non-matching character between S and T.
1. If S matches all characters in T, then check if there is an extra character at the end of T. (Append operation)
2. If | n – m | == 1, that means we must skip this non-matching character only in T and make sure the remaining characters between S and T are exactly matching. (Insert operation)
3. If | n – m | == 0, then we skip both non-matching characters in S and T and make sure the remaining characters between S and T are exactly matching. (Modify operation)
public static boolean isOneEditDistance(String s, String t) { int m = s.length(), n = t.length(); if(m > n) return isOneEditDistance(t, s); if(n - m > 1) return false; int i = 0, diff = n - m; while(i < m && s.charAt(i) == t.charAt(i)) { i++; } //if s matches all characters in t //Append: check if there is an extra character at the end of T. if(i == m && diff > 0) return true; //if |m - n|=0 //Modify: skip both non-matching characters in S and T and make sure the remaining characters are matching if(diff == 0) i++; //if |m - n|=1 //Insert: skip this non-matching character only in T and make sure the remaining characters are matching while(i < m && s.charAt(i) == t.charAt(i + diff)) { i++; } if(i == m) return true; return false; }
No comments:
Post a Comment