📌  相关文章
📜  要使一个字符串等于另一个字符串的最长子字符串的长度

📅  最后修改于: 2021-04-24 05:33:57             🧑  作者: Mango

给定两个字符串str1str2 ,其中str2str1的子序列,任务是找到str1的最长子字符串的长度,将其删除后,使字符串str2str1相等。

例子:

天真的方法:最简单的方法是生成str1的所有可能子字符串,并为每个子字符串将其从str1中删除,并检查结果字符串是否等于str2 。打印最长的此类子字符串的长度。

时间复杂度: O(2 N )
辅助空间: O(N)

高效方法:为了优化上述方法,我们的想法是在str1中找到str2的出现。从左到右遍历两个字符串,并检查两个字符是否相等。如果发现是正确的,则在两个字符串向右进行。否则,仅在str2中向右进行。同样,找到STR1 STR2最后一次出现,遍历从右到左字符串和同样进行。请按照以下步骤解决问题:

  1. 初始化变量res = 0以存储最长的已删除子字符串的长度。
  2. 创建一个数组pos []来存储str1中第一次出现的str2的位置
  3. 从左到右遍历两个字符串,并通过删除一些str1字符来存储第一次出现的str2的位置。
  4. 初始化变量lastPos = length(str1)-1,以通过删除str1的某些字符来存储当前字符在最后一次出现的str2中的位置。
  5. 从右到左遍历两个字符串,并检查两个字符匹配,然后在pos []中找到str2当前字符的位置,否则继续。
  6. 如果res >( lastPospos [i-1] -1),则更新res = lastPos – pos [i-1] -1。
  7. 最后,返回res

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
  
#include 
using namespace std;
  
// Function to print the length
// of longest substring to be deleted
int longDelSub(string str1, string str2)
{
    // Stores the length of string
    int N = str1.size();
    int M = str2.size();
  
    // Store the position of
    // previous matched
    // character of str1
    int prev_pos = 0;
  
    // Store the position of first
    // occurrence of str2 in str1
    int pos[M];
  
    // Find the position of the
    // first occurrence of str2
    for (int i = 0; i < M; i++) {
  
        // Store the index of str1
        int index = prev_pos;
  
        // If both characters not matched
        while (index < N
               && str1[index] != str2[i]) {
            index++;
        }
  
        pos[i] = index;
        prev_pos = index + 1;
    }
  
    // Store the length of the
    // longest deleted substring
    int res = N - prev_pos;
  
    prev_pos = N - 1;
  
    // Store the position of last
    // occurrence of str2 in str1
    for (int i = M - 1; i >= 0; i--) {
        int index = prev_pos;
  
        // If both characters not matched
        while (index >= 0
               && str1[index] != str2[i]) {
            index--;
        }
  
        // Update res
        if (i != 0) {
            res = max(
                res,
                index - pos[i - 1] - 1);
        }
  
        prev_pos = index - 1;
    }
  
    // Update res.
    res = max(res, prev_pos + 1);
  
    return res;
}
  
// Driver Code
int main()
{
    // Given string
    string str1 = "GeeksforGeeks";
    string str2 = "forks";
  
    // Function Call
    cout << longDelSub(str1, str2);
    return 0;
}


Java
// Java program to implement 
// the above approach 
import java.io.*;
  
class GFG{
  
// Function to print the length
// of longest substring to be deleted
static int longDelSub(String str1, String str2)
{
      
    // Stores the length of string
    int N = str1.length();
    int M = str2.length();
  
    // Store the position of
    // previous matched
    // character of str1
    int prev_pos = 0;
  
    // Store the position of first
    // occurrence of str2 in str1
    int pos[] = new int[M];
  
    // Find the position of the
    // first occurrence of str2
    for(int i = 0; i < M; i++)
    {
          
        // Store the index of str1
        int index = prev_pos;
  
        // If both characters not matched
        while (index < N && 
               str1.charAt(index) != 
               str2.charAt(i))
        {
            index++;
        }
  
        pos[i] = index;
        prev_pos = index + 1;
    }
  
    // Store the length of the
    // longest deleted substring
    int res = N - prev_pos;
  
    prev_pos = N - 1;
  
    // Store the position of last
    // occurrence of str2 in str1
    for(int i = M - 1; i >= 0; i--)
    {
        int index = prev_pos;
  
        // If both characters not matched
        while (index >= 0 && 
               str1.charAt(index) != 
               str2.charAt(i)) 
        {
            index--;
        }
  
        // Update res
        if (i != 0)
        {
            res = Math.max(res, 
                           index - 
                           pos[i - 1] - 1);
        }
        prev_pos = index - 1;
    }
  
    // Update res.
    res = Math.max(res, prev_pos + 1);
  
    return res;
}
  
// Driver Code
public static void main (String[] args)
{
      
    // Given string
    String str1 = "GeeksforGeeks";
    String str2 = "forks";
  
    // Function call
    System.out.print(longDelSub(str1, str2));
}
}
  
// This code is contributed by code_hunt


Python3
# Python3 program to implement 
# the above approach 
  
# Function to prthe length
# of longest substring to be deleted
def longDelSub(str1, str2):
      
    # Stores the length of string
    N = len(str1)
    M = len(str2)
  
    # Store the position of
    # previous matched
    # character of str1
    prev_pos = 0
  
    # Store the position of first
    # occurrence of str2 in str1
    pos = [0] * M
  
    # Find the position of the
    # first occurrence of str2
    for i in range(M):
  
        # Store the index of str1
        index = prev_pos
  
        # If both characters not matched
        while (index < N and 
          str1[index] != str2[i]):
            index += 1
          
        pos[i] = index
        prev_pos = index + 1
      
    # Store the length of the
    # longest deleted substring
    res = N - prev_pos
  
    prev_pos = N - 1
  
    # Store the position of last
    # occurrence of str2 in str1
    for i in range(M - 1, -1, -1):
        index = prev_pos
  
        # If both characters not matched
        while (index >= 0 and 
          str1[index] != str2[i]):
            index -= 1
          
        # Update res
        if (i != 0) :
            res = max(res, 
                      index - 
                      pos[i - 1] - 1)
          
        prev_pos = index - 1
      
    # Update res.
    res = max(res, prev_pos + 1)
  
    return res
  
# Driver Code
  
# Given string
str1 = "GeeksforGeeks"
str2 = "forks"
  
# Function call
print(longDelSub(str1, str2))
  
# This code is contributed by code_hunt


C#
// C# program to implement 
// the above approach 
using System;
  
class GFG{
      
// Function to print the length
// of longest substring to be deleted
static int longDelSub(string str1,
                      string str2)
{
      
    // Stores the length of string
    int N = str1.Length;
    int M = str2.Length;
  
    // Store the position of
    // previous matched
    // character of str1
    int prev_pos = 0;
  
    // Store the position of first
    // occurrence of str2 in str1
    int[] pos = new int[M];
  
    // Find the position of the
    // first occurrence of str2
    for(int i = 0; i < M; i++) 
    {
  
        // Store the index of str1
        int index = prev_pos;
  
        // If both characters not matched
        while (index < N && 
          str1[index] != str2[i])
        {
            index++;
        }
  
        pos[i] = index;
        prev_pos = index + 1;
    }
  
    // Store the length of the
    // longest deleted substring
    int res = N - prev_pos;
  
    prev_pos = N - 1;
  
    // Store the position of last
    // occurrence of str2 in str1
    for(int i = M - 1; i >= 0; i--)
    {
        int index = prev_pos;
  
        // If both characters not matched
        while (index >= 0 && 
          str1[index] != str2[i])
        {
            index--;
        }
  
        // Update res
        if (i != 0)
        {
            res = Math.Max(res, 
                           index - 
                           pos[i - 1] - 1);
        }
        prev_pos = index - 1;
    }
  
    // Update res.
    res = Math.Max(res, prev_pos + 1);
  
    return res;
}
  
// Driver code
public static void Main()
{
      
    // Given string
    string str1 = "GeeksforGeeks";
    string str2 = "forks";
  
    // Function call
    Console.Write(longDelSub(str1, str2));
}
}
  
// This code is contributed by code_hunt


输出:
5

时间复杂度: O(N + M)
辅助空间: O(M)