I came across this question recently:
Given two strings, return true if they are one edit away from each other,else return false.
An edit is insert/replace/delete a character.
Ex. {"abc","ab"}->true, {"abc","adc"}->true, {"abc","cab"}->false
One way to solve this problem would be to find the edit distance between the two strings using dynamic programming, and check if it is 1. That would take O(N2) time. Is there a way to do this in linear time, as we've to only check if they are 1 edit away?
The code I wrote below works for most cases, but fails for cases like {"m",""}
public boolean isOneEditDistance(String s1,String s2){
if(s1==null || s2==null)
return true;
if(s1.equals(s2))
return false;
if (Math.abs(s1.length() - s2.length()) > 1)
return false;
int i = -1;
int j = -1;
while (true)
{
i++;
j++;
if (i == s1.length())
return true;
if (s1.charAt(i) == s2.charAt(j))
continue;
if (i != j)
return false;
if (s1.length() < s2.length())
i--;
else
j--;
}
}
Here is the solution for finding the one edit in O(n). Below are the scenario, I have covered in the implementation.
private static boolean isOneEdit(String first, String second) {
// if the input string are same
if (first.equals(second))
return false;
int len1 = first.length();
int len2 = second.length();
// If the length difference of the stings is more than 1, return false.
if ((len1 - len2) > 1 || (len2 - len1) > 1 ) {
return false;
}
int i = 0, j = 0;
int diff = 0;
while (i<len1 && j<len2) {
char f = first.charAt(i);
char s = second.charAt(j);
if (f != s) {
diff++;
if (len1 > len2)
i++;
if (len2 > len1)
j++;
if (len1 == len2)
i++; j++;
}
else{
i++; j++;
}
if (diff > 1) {
return false;
}
}
// If the length of the string is not same. ex. "abc" and "abde" are not one edit distance.
if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) {
return false;
}
return true;
}
Java version may be like below:
public static boolean oneEdit(String w1, String w2)
{
char[] word1= w1.trim().toCharArray();
char[] word2 = w2.trim().toCharArray();
int length1=word1.length;
int length2=word2.length;
if(Math.abs(length2-length1) > 1) return false;
Arrays.sort(word1);
Arrays.sort(word2);
int length = word1.length >= word2.length? word2.length:word1.length; //take the minimum length
int falseCounter=0;
for(int i=0; i < length; i++ ) {
if(word1[i] != word2[i] && ++falseCounter > 1){
return false;
}
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With