Open In App

Check if edit distance between two strings is one

Improve
Improve
Like Article
Like
Save
Share
Report

An edit between two strings is one of the following changes. 

  1. Add a character
  2. Delete a character
  3. Change a character

Given two string s1 and s2, find if s1 can be converted to s2 with exactly one edit. Expected time complexity is O(m+n) where m and n are lengths of two strings. 

Examples: 

Input:  s1 = "geeks", s2 = "geek"
Output: yes
Number of edits is 1
Input:  s1 = "geeks", s2 = "geeks"
Output: no
Number of edits is 0
Input:  s1 = "geaks", s2 = "geeks"
Output: yes
Number of edits is 1
Input:  s1 = "peaks", s2 = "geeks"
Output: no
Number of edits is 2

A Simple Solution is to find Edit Distance using Dynamic programming. If distance is 1, then return true, else return false. Time complexity of this solution is O(n2)

An Efficient Solution is to simultaneously traverse both strings and keep track of count of different characters. Below is complete algorithm.

Let the input strings be s1 and s2 and lengths of input 
strings be m and n respectively.
1) If difference between m an n is more than 1, 
     return false.
2) Initialize count of edits as 0.
3) Start traversing both strings from first character.
    a) If current characters don't match, then
       (i)   Increment count of edits
       (ii)  If count becomes more than 1, return false
       (iii) If length of one string is more, then only
             possible  edit is to remove a character.
             Therefore, move ahead in larger string.
       (iv)  If length is same, then only possible edit
             is to  change a character. Therefore, move
             ahead in both strings. 
    b) Else, move ahead in both strings. 

Below is the implementation of the above idea :

C++




// C++ program to check if given two strings are
// at distance one.
#include <bits/stdc++.h>
using namespace std;
 
// Returns true if edit distance between s1 and
// s2 is one, else false
bool isEditDistanceOne(string s1, string s2)
{
    // Find lengths of given strings
    int m = s1.length(), n = s2.length();
 
    // If difference between lengths is more than
    // 1, then strings can't be at one distance
    if (abs(m - n) > 1)
        return false;
 
    int count = 0; // Count of edits
 
    int i = 0, j = 0;
    while (i < m && j < n)
    {
        // If current characters don't match
        if (s1[i] != s2[j])
        {
            if (count == 1)
                return false;
 
            // If length of one string is
            // more, then only possible edit
            // is to remove a character
            if (m > n)
                i++;
            else if (m< n)
                j++;
            else //Iflengths of both strings is same
            {
                i++;
                j++;
            }
             
            // Increment count of edits
            count++;
        }
 
        else // If current characters match
        {
            i++;
            j++;
        }
    }
 
    // If last character is extra in any string
    if (i < m || j < n)
        count++;
 
    return count == 1;
}
 
// Driver program
int main()
{
   string s1 = "gfg";
   string s2 = "gf";
   isEditDistanceOne(s1, s2)?
           cout << "Yes": cout << "No";
   return 0;
}


Java




// Java program to check if given
// two strings are at distance one.
class GFG
{
// Returns true if edit distance
// between s1 and s2 is one, else false
static boolean isEditDistanceOne(String s1,
                                 String s2)
{
    // Find lengths of given strings
    int m = s1.length(), n = s2.length();
 
    // If difference between lengths is
    // more than 1, then strings can't
    // be at one distance
    if (Math.abs(m - n) > 1)
        return false;
 
    int count = 0; // Count of edits
 
    int i = 0, j = 0;
    while (i < m && j < n)
    {
        // If current characters don't match
        if (s1.charAt(i) != s2.charAt(j))
        {
            if (count == 1)
                return false;
 
            // If length of one string is
            // more, then only possible edit
            // is to remove a character
            if (m > n)
                i++;
            else if (m< n)
                j++;
            else // Iflengths of both strings
                // is same
            {
                i++;
                j++;
            }
             
            // Increment count of edits
            count++;
        }
 
        else // If current characters match
        {
            i++;
            j++;
        }
    }
 
    // If last character is extra
    // in any string
    if (i < m || j < n)
        count++;
 
    return count == 1;
}
 
// driver code
public static void main (String[] args)
{
    String s1 = "gfg";
    String s2 = "gf";
    if(isEditDistanceOne(s1, s2))
        System.out.print("Yes");
    else
        System.out.print("No");
}
}
 
// This code is contributed by Anant Agarwal.


Python3




# Python program to check if given two strings are
# at distance one
 
# Returns true if edit distance between s1 and s2 is
# one, else false
def isEditDistanceOne(s1, s2):
 
    # Find lengths of given strings
    m = len(s1)
    n = len(s2)
 
    # If difference between lengths is more than 1,
    # then strings can't be at one distance
    if abs(m - n) > 1:
        return false
 
    count = 0    # Count of isEditDistanceOne
 
    i = 0
    j = 0
    while i < m and j < n:
        # If current characters dont match
        if s1[i] != s2[j]:
            if count == 1:
                return false
 
            # If length of one string is
            # more, then only possible edit
            # is to remove a character
            if m > n:
                i+=1
            elif m < n:
                j+=1
            else:    # If lengths of both strings is same
                i+=1
                j+=1
 
            # Increment count of edits
            count+=1
 
        else:    # if current characters match
            i+=1
            j+=1
 
    # if last character is extra in any string
    if i < m or j < n:
        count+=1
 
    return count == 1
 
# Driver program
s1 = "gfg"
s2 = "gf"
if isEditDistanceOne(s1, s2):
    print ("Yes")
else:
    print ("No")
 
# This code is contributed by Bhavya Jain


C#




// C# program to check if given
// two strings are at distance one.
using System;
 
class GFG
{
 
// Returns true if edit distance
// between s1 and s2 is one, else false
static bool isEditDistanceOne(String s1,
                              String s2)
{
     
    // Find lengths of given strings
    int m = s1.Length, n = s2.Length;
 
    // If difference between lengths is
    // more than 1, then strings can't
    // be at one distance
    if (Math.Abs(m - n) > 1)
        return false;
 
        // Count of edits
        int count = 0;
        int i = 0, j = 0;
         
    while (i < m && j < n)
    {
        // If current characters
        // don't match
        if (s1[i] != s2[j])
        {
            if (count == 1)
                return false;
 
            // If length of one string is
            // more, then only possible edit
            // is to remove a character
            if (m > n)
                i++;
            else if (m< n)
                j++;
                 
             // If lengths of both
             // strings is same
            else
            {
                i++;
                j++;
            }
             
            // Increment count of edits
            count++;
        }
 
        // If current characters match
        else
        {
            i++;
            j++;
        }
    }
 
    // If last character is extra
    // in any string
    if (i < m || j < n)
        count++;
 
    return count == 1;
}
 
// Driver code
public static void Main ()
{
    String s1 = "gfg";
    String s2 = "gf";
    if(isEditDistanceOne(s1, s2))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("No");
}
}
 
// This code is contributed by Sam007.


Javascript




<script>
    // Javascript program to check if given
    // two strings are at distance one.
     
    // Returns true if edit distance
    // between s1 and s2 is one, else false
    function isEditDistanceOne(s1, s2)
    {
 
        // Find lengths of given strings
        let m = s1.length, n = s2.length;
 
        // If difference between lengths is
        // more than 1, then strings can't
        // be at one distance
        if (Math.abs(m - n) > 1)
            return false;
 
            // Count of edits
            let count = 0;
            let i = 0, j = 0;
 
        while (i < m && j < n)
        {
            // If current characters
            // don't match
            if (s1[i] != s2[j])
            {
                if (count == 1)
                    return false;
 
                // If length of one string is
                // more, then only possible edit
                // is to remove a character
                if (m > n)
                    i++;
                else if (m< n)
                    j++;
 
                 // If lengths of both
                 // strings is same
                else
                {
                    i++;
                    j++;
                }
 
                // Increment count of edits
                count++;
            }
 
            // If current characters match
            else
            {
                i++;
                j++;
            }
        }
 
        // If last character is extra
        // in any string
        if (i < m || j < n)
            count++;
 
        return count == 1;
    }
     
    let s1 = "gfg";
    let s2 = "gf";
    if(isEditDistanceOne(s1, s2))
        document.write("Yes");
    else
        document.write("No");
     
    // This code is contributed by decode2207.
</script>


PHP




<?php
// PHP program to check if given
// two strings are at distance one.
 
// Returns true if edit distance
// between s1 and s2 is one, else
// false
function isEditDistanceOne($s1, $s2)
{
     
    // Find lengths of given strings
    $m = strlen($s1);
    $n = strlen($s2);
 
    // If difference between
    // lengths is more than
    // 1, then strings can't
    // be at one distance
    if (abs($m - $n) > 1)
        return false;
 
    // Count of edits
    $count = 0;
 
    $i = 0; $j = 0;
    while ($i < $m && $j < $n)
    {
        // If current characters
        // don't match
        if ($s1[$i] != $s2[$j])
        {
            if ($count == 1)
                return false;
 
            // If length of one string is
            // more, then only possible edit
            // is to remove a character
            if ($m > $n)
                $i++;
            else if ($m< $n)
                $j++;
                 
             // If lengths of both
             // strings is same
            else
            {
                $i++;
                $j++;
            }
             
            // Increment count of edits
            $count++;
        }
 
        // If current characters
        // match
        else
        {
            $i++;
            $j++;
        }
    }
 
    // If last character is
    // extra in any string
    if ($i < $m || $j < $n)
        $count++;
 
    return $count == 1;
}
 
// Driver Code
$s1 = "gfg";
$s2 = "gf";
if(isEditDistanceOne($s1, $s2))
    echo "Yes";
else
    echo "No";
 
// This code is contributed by nitin mittal.
?>


Output

Yes



Time complexity: O(n) 
Auxiliary Space: O(1)

Approach#2: Using dynamic programming

The approach of this code is to calculate the edit distance between two strings using dynamic programming and then check if it is equal to one or not. If the absolute difference in length of the strings is greater than one, it returns False without calculating the edit distance. Otherwise, it fills a 2D array with the minimum number of operations required to transform one string into another, using the operations of insertion, removal, and replacement. Finally, it returns True if the edit distance is equal to one, and False otherwise.

Algorithm

1. If the absolute difference between the lengths of s1 and s2 is greater than 1, return False.
2. Create a 2D array dp of size (n+1) x (m+1) where n is the length of s1 and m is the length of s2.
3. Initialize the first row and first column of dp with values from 0 to m and 0 to n respectively.
4. Traverse the dp array from (1,1) to (n,m) and check the following conditions:
If s1[i-1] and s2[j-1] are equal, set dp[i][j] to dp[i-1][j-1].
Otherwise, set dp[i][j] to 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]).
5. Return True if dp[n][m] is 1, else return False.

C++




#include <iostream>
#include <string>
using namespace std;
 
// Function to check if the edit distance between two strings is one
bool isEditDistanceOne(string s1, string s2) {
    int n = s1.length();   // Get the length of the first string
    int m = s2.length();   // Get the length of the second string
 
    if (abs(n - m) > 1)   // If the absolute difference in string lengths
                           // is more than 1, return false
        return false;
 
    int dp[n + 1][m + 1];  // Create a 2D array for dynamic programming
 
    // Initialize the dynamic programming array
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (i == 0)
                dp[i][j] = j;  // Initialize the first row with values from 0 to j
            else if (j == 0)
                dp[i][j] = i;  // Initialize the first column with values from 0 to i
            else if (s1[i - 1] == s2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];  // Characters match, no operation needed
            else
                dp[i][j] = 1 + min(dp[i][j - 1],
                           min(dp[i - 1][j], dp[i - 1][j - 1]));
                // Characters don't match, calculate the minimum of insert,
                // remove, or replace operations
        }
    }
 
    return dp[n][m] == 1;  // Return true if the edit distance is one
}
 
int main() {
    string s1 = "gfg";
    string s2 = "gf";
    cout << (isEditDistanceOne(s1, s2) ? "true" : "false") << endl;
    return 0;
}


Java




public class EditDistanceOne {
    // Function to check if the edit distance between two strings is one
    public static boolean isEditDistanceOne(String s1, String s2) {
        int n = s1.length();   // Get the length of the first string
        int m = s2.length();   // Get the length of the second string
 
        if (Math.abs(n - m) > 1)   // If the absolute difference in string lengths
                                   // is more than 1, return false
            return false;
 
        int[][] dp = new int[n + 1][m + 1];  // Create a 2D array for dynamic programming
 
        // Initialize the dynamic programming array
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                if (i == 0)
                    dp[i][j] = j;  // Initialize the first row with values from 0 to j
                else if (j == 0)
                    dp[i][j] = i;  // Initialize the first column with values from 0 to i
                else if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    dp[i][j] = dp[i - 1][j - 1];  // Characters match, no operation needed
                else
                    dp[i][j] = 1 + Math.min(dp[i][j - 1],
                               Math.min(dp[i - 1][j], dp[i - 1][j - 1]));
                    // Characters don't match, calculate the minimum of insert,
                    // remove, or replace operations
            }
        }
 
        return dp[n][m] == 1// Return true if the edit distance is one
    }
 
    public static void main(String[] args) {
        String s1 = "gfg";
        String s2 = "gf";
        System.out.println(isEditDistanceOne(s1, s2));
    }
}


Python3




def is_edit_distance_one(s1, s2):
    n = len(s1)
    m = len(s2)
     
    if abs(n - m) > 1:
        return False
     
    dp = [[0 for j in range(m+1)] for i in range(n+1)]
     
    for i in range(n+1):
        for j in range(m+1):
            if i == 0:
                dp[i][j] = j
            elif j == 0:
                dp[i][j] = i
            elif s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1 + min(dp[i][j-1],      # Insert
                                   dp[i-1][j],      # Remove
                                   dp[i-1][j-1])    # Replace
     
    return dp[n][m] == 1
s1 = "gfg"
s2 = "gf"
print(is_edit_distance_one(s1, s2))


C#




using System;
 
class GFG
{
    // Function to check if the edit distance between two strings is one
    static bool IsEditDistanceOne(string s1, string s2)
    {
        int n = s1.Length; // Get the length of the first string
        int m = s2.Length; // Get the length of the second string
         
        // If the absolute difference in string lengths
        // is more than 1, return false
        if (Math.Abs(n - m) > 1)
        {
            return false;
        }
         
        // Create a 2D array for dynamic programming
        int[,] dp = new int[n + 1, m + 1];
 
        // Initialize the dynamic programming array
        for (int i = 0; i <= n; i++)
        {
            for (int j = 0; j <= m; j++)
            {
                if (i == 0)
                {
                    // Initialize the first row with values from 0 to j
                    dp[i, j] = j;
                }
                else if (j == 0)
                {
                    // Initialize the first column with values from 0 to i
                    dp[i, j] = i;
                }
                else if (s1[i - 1] == s2[j - 1])
                {
                    // Characters match, no operation needed
                    dp[i, j] = dp[i - 1, j - 1];
                }
                else
                {
                    // Characters don't match, calculate the minimum of insert,
                    // remove, or replace operations
                    dp[i, j] = 1 + Math.Min(dp[i, j - 1], Math.Min(dp[i - 1, j], dp[i - 1, j - 1]));
                }
            }
        }
        // Return true if the edit distance is one
        return dp[n, m] == 1;
    }
 
    static void Main()
    {
        string s1 = "gfg";
        string s2 = "gf";
        Console.WriteLine(IsEditDistanceOne(s1, s2) ? "true" : "false");
    }
}


Javascript




// This function checks if the edit distance between two strings is one
function is_edit_distance_one(s1, s2) {
    let n = s1.length;
    let m = s2.length;
 
    // If the absolute difference between the lengths of the strings is greater than 1, edit distance cannot be one
    if (Math.abs(n - m) > 1) {
        return false;
    }
 
    // Create a 2D array for dynamic programming
    let dp = Array.from(Array(n + 1), () => new Array(m + 1).fill(0));
 
    // Fill up the dp array
    for (let i = 0; i <= n; i++) {
        for (let j = 0; j <= m; j++) {
            if (i == 0) {
                // If s1 is empty, insert all characters of s2 to s1
                dp[i][j] = j;
            } else if (j == 0) {
                // If s2 is empty, remove all characters of s1
                dp[i][j] = i;
            } else if (s1[i - 1] == s2[j - 1]) {
                // If the characters are same, no operation is needed
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                // If the characters are different, we need to perform one of the three operations - insert, remove or replace
                dp[i][j] = 1 + Math.min(dp[i][j - 1], // Insert
                    dp[i - 1][j], // Remove
                    dp[i - 1][j - 1]); // Replace
            }
        }
    }
 
    // If edit distance is 1, return true else false
    return dp[n][m] == 1;
}
 
// Example usage
let s1 = "gfg";
let s2 = "gf";
console.log(is_edit_distance_one(s1, s2));


Output

True



Time complexity: O(n^2)
Auxiliary Space: O(n^2)



Last Updated : 27 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads