Length of longest substring to be deleted to make a string equal to another string


In this article, we will discuss the problem of finding the length of the longest substring that needs to be deleted to make one string equal to another. We will first understand the problem statement and then explore both the naive and efficient approaches to solve this problem, along with their respective algorithms and time complexities. Lastly, we will implement the solution.

Problem Statement

Given two strings, A and B, determine the length of the longest substring that needs to be deleted from string A to make it equal to string B.

Naive Approach

The naive approach is to generate all possible substrings of string A, delete each of them one by one, and check if the resultant string is equal to string B. If it is, we will store the length of the deleted substring. Finally, we will return the maximum length among all the deleted substrings.

Algorithm (Naive)

  • Initialize maxLength to 0.

  • Generate all possible substrings of string A

  • For each substring, delete it from string A and check if the resultant string is equal to string B.

  • If yes, update maxLength to the maximum of maxLength and the length of the deleted substring.

  • Return maxLength.

Code (Naive)

Example

Following are the programs to the above algorithm −

#include <stdio.h>
#include <string.h>

int longestSubstringToDelete(char A[], char B[]) {
   int maxLength = 0;
    
   for (int i = 0; i < strlen(A); i++) {
      for (int j = i; j < strlen(A); j++) {
         // Create a temporary string and remove the substring from i to j
         char temp[strlen(A) + 1];
         strcpy(temp, A);
         memmove(temp + i, temp + j + 1, strlen(temp) - j);
            
         // Compare the temporary string with string B
         if (strcmp(temp, B) == 0) {
            maxLength = (j - i + 1 > maxLength) ? j - i + 1 : maxLength;
         }
      }
   }
    
   return maxLength;
}

int main() {
   char A[] = "abcde";
   char B[] = "acde";
    
   printf("Length of longest substring to be deleted: %d\n", longestSubstringToDelete(A, B));
    
   return 0;
}

Output

Length of longest substring to be deleted: 1
#include <iostream>
#include <string>
#include <algorithm>

int longestSubstringToDelete(std::string A, std::string B) {
   int maxLength = 0;
   
   for (int i = 0; i < A.length(); i++) {
      for (int j = i; j < A.length(); j++) {
         std::string temp = A;
         temp.erase(i, j - i + 1);
   
         if (temp == B) {
            maxLength = std::max(maxLength, j - i + 1);
         }
      }
   }
   
   return maxLength;
}

int main() {
   std::string A = "abcde";
   std::string B = "acde";
   
   std::cout << "Length of longest substring to be deleted: " << longestSubstringToDelete(A, B) << std::endl;
   
   return 0;
}

Output

Length of longest substring to be deleted: 1
public class Main {
   public static int longestSubstringToDelete(String A, String B) {
      int maxLength = 0;
        
      for (int i = 0; i < A.length(); i++) {
         for (int j = i; j < A.length(); j++) {
            // Create a temporary StringBuilder and remove the substring from i to j
            StringBuilder temp = new StringBuilder(A);
            temp.delete(i, j + 1);
            
            // Compare the temporary StringBuilder with string B
            if (temp.toString().equals(B)) {
               maxLength = Math.max(maxLength, j - i + 1);
            }
         }
      }
        
      return maxLength;
   }

   public static void main(String[] args) {
      String A = "abcde";
      String B = "acde";
      
      System.out.println("Length of longest substring to be deleted: " + longestSubstringToDelete(A, B));
   }
}

Output

Length of longest substring to be deleted: 1
def longest_substring_to_delete(A, B):
   max_length = 0
    
   for i in range(len(A)):
      for j in range(i, len(A)):
         # Create a temporary string and remove the substring from i to j
         temp = A[:i] + A[j+1:]
            
         # Compare the temporary string with string B
         if temp == B:
            max_length = max(max_length, j - i + 1)
                
   return max_length

def main():
   A = "abcde"
   B = "acde"
    
   print("Length of longest substring to be deleted:", longest_substring_to_delete(A, B))

if __name__ == "__main__":
   main()

Output

Length of longest substring to be deleted: 1

Time Complexity (Naive) − O(n^3), where n is the length of string A.

Efficient Approach

The efficient approach to solve this problem is to find the longest common subsequence (LCS) of both strings. The length of the longest substring that needs to be deleted from string A to make it equal to string B is the difference between the length of string A and the length of the LCS.

Algorithm (Efficient)

  • Find the longest common subsequence (LCS) of string A and string B.

  • Return the difference between the length of string A and the length of the LCS.

Code (Efficient)

Example

Following are the programs to the above algorithm −

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Function to calculate longest common subsequence
int longestCommonSubsequence(char A[], char B[]) {
   int m = strlen(A);
   int n = strlen(B);
   
   // Create a 2D array to store LCS lengths
   int dp[m + 1][n + 1];
   for (int i = 0; i <= m; i++) {
      for (int j = 0; j <= n; j++) {
         dp[i][j] = 0; // Initialize all values to 0
      }
   }
   
   for (int i = 1; i <= m; i++) {
      for (int j = 1; j <= n; j++) {
         if (A[i - 1] == B[j - 1]) {
            dp[i][j] = 1 + dp[i - 1][j - 1];
         } else {
            dp[i][j] = (dp[i - 1][j] > dp[i][j - 1]) ? dp[i - 1][j] : dp[i][j - 1];
         }
      }
   }
   return dp[m][n];
}

// Function to calculate length of longest substring to be deleted
int longestSubstringToDelete(char A[], char B[]) {
   int lcsLength = longestCommonSubsequence(A, B);
   return strlen(A) - lcsLength;
}

int main() {
   char A[] = "abcde";
   char B[] = "acde";
   
   printf("Length of longest substring to be deleted: %d\n", longestSubstringToDelete(A, B));
   
   return 0;
}

Output

Length of longest substring to be deleted: 1
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int longestCommonSubsequence(std::string A, std::string B) {
   int m = A.length();
   int n = B.length();
   std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0));
   
   for (int i = 1; i <= m; i++) {
      for (int j = 1; j <= n; j++) {
         if (A[i - 1] == B[j - 1]) {
            
            dp[i][j] = 1 + dp[i - 1][j - 1];
         } else {
            dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]);
         }
      }
   }
   return dp[m][n];
}

int longestSubstringToDelete(std::string A, std::string B) {
   int lcsLength = longestCommonSubsequence(A, B);
   return A.length() - lcsLength;
}

int main() {
   std::string A = "abcde";
   std::string B = "acde";
   std::cout << "Length of longest substring to be deleted: " << longestSubstringToDelete(A, B) << std::endl;
   
   return 0;
}

Output

Length of longest substring to be deleted: 1
public class Main {
   public static int longestCommonSubsequence(String A, String B) {
      int m = A.length();
      int n = B.length();
        
      // Create a 2D array to store LCS lengths
        int[][] dp = new int[m + 1][n + 1];
        
      for (int i = 1; i <= m; i++) {
         for (int j = 1; j <= n; j++) {
            if (A.charAt(i - 1) == B.charAt(j - 1)) {
               dp[i][j] = 1 + dp[i - 1][j - 1];
            } else {
               dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
         }
      }
      return dp[m][n];
   }

   public static int longestSubstringToDelete(String A, String B) {
      int lcsLength = longestCommonSubsequence(A, B);
      return A.length() - lcsLength;
   }

   public static void main(String[] args) {
      String A = "abcde";
      String B = "acde";
        
      System.out.println("Length of longest substring to be deleted: " + longestSubstringToDelete(A, B));
   }
}

Output

Length of longest substring to be deleted: 1
def longest_common_subsequence(A, B):
   m = len(A)
   n = len(B)
   
   # Create a 2D list to store LCS lengths
   dp = [[0] * (n + 1) for _ in range(m + 1)]
   
   for i in range(1, m + 1):
      for j in range(1, n + 1):
         if A[i - 1] == B[j - 1]:
            dp[i][j] = 1 + dp[i - 1][j - 1]
         else:
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
    
   return dp[m][n]

def longest_substring_to_delete(A, B):
   lcs_length = longest_common_subsequence(A, B)
   return len(A) - lcs_length

def main():
   A = "abcde"
   B = "acde"
    
   print("Length of longest substring to be deleted:", longest_substring_to_delete(A, B))

if __name__ == "__main__":
   main()

Output

Length of longest substring to be deleted: 1

Time Complexity (Efficient) − O(m * n), where m is the length of string A and n is the length of string B.

Conclusion

In this article, we explored the problem of finding the length of the longest substring that needs to be deleted to make one string equal to another. We discussed both the naive and efficient approaches to solve this problem, along with their algorithms and time complexities. The efficient approach, which utilizes the longest common subsequence concept, provides a significant improvement in time complexity over the naive approach.

Updated on: 23-Oct-2023

111 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements