Given two strings, find if they are one edit away from each other

codewarrior picture codewarrior · Sep 7, 2015 · Viewed 12k times · Source

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--;
    }
}

Answer

YoungHobbit picture YoungHobbit · Sep 7, 2015

Here is the solution for finding the one edit in O(n). Below are the scenario, I have covered in the implementation.

  1. The length difference between two input strings should not be more than 1.
  2. When the length of the strings is same, the number of different chars should not be more than 1.
  3. If the length difference is 1, then either one char can be inserted in the short string or deleted from the longer string. Considering that, the number of different char should not be more than 1.
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;
}