📌  相关文章
📜  查找包含另一个字符串作为子序列的给定字符串的最小子字符串的长度

📅  最后修改于: 2022-05-13 01:56:04.386000             🧑  作者: Mango

查找包含另一个字符串作为子序列的给定字符串的最小子字符串的长度

给定两个字符串AB ,任务是找到以B作为子序列的A的最小子字符串。如果A中有多个这样的子字符串,则返回具有最小起始索引的子字符串。

例子 :

朴素方法:解决给定问题的最简单方法是检查字符串B 作为 A 的每个子字符串中的子序列出现。
在这些子串中,答案将是长度最短且索引最小的一个。

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

高效方法:上述方法也可以通过使用动态规划进行优化,因为上述问题具有重叠子问题和最优子结构。子问题可以存储在dp[][]记忆中,其中dp[i][j]表示在子串A(0…i)中存在一个对应于B(0…j)的子序列,该子序列从索引dp[我][j] 。请按照以下步骤解决问题:

  • 初始化一个全局多维数组dp[100][100] ,所有值都为-1 ,存储每个dp状态的结果。
  • dp表中的每一列代表字符串B中的一个字符。
  • 初始化dp数组的第一列,即将字符串A的字符串前缀
  • 填充dp表的其余列。对于字符串B中位置'j'的特定字符,检查字符串A中是否存在匹配字符。
    • 如果A[i] == B[j] ,则字符串A中所需子字符串的起始索引等于字符串B的前j – 1 个字符与字符串的前i – 1 个字符匹配时的起始索引一个
    • 如果A[i] != B[j] ,则字符串A中所需子字符串的起始索引等于字符串B的前j个字符与字符串A的前i-1 个字符匹配时的起始索引。
  • 检查dp最后一列中的任何值是否大于或等于0 。对于字符串A中的特定索引i ,如果dp[i][b – 1] >= 0 ,则所需的以B作为子序列的子字符串是A[dp[i][b-1] : i] 。用尽可能短的子字符串更新答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Stores the dp-states
int dp[100][100];
 
// Function to find the smallest substring in string A which
// contains string B as a subsequence.
string smallestSubstring(string& A, string& B)
{
    // Size of string A
    int a = A.size();
 
    // Size of string B
    int b = B.size();
 
    // Initializing the first column of dp array.
    // Storing the occurence of first character of string B
    // in first (i + 1) characters of string A.
    for (int i = 0; i < a; ++i) {
 
        // If the current character of string A does not
        // match the first character of string B.
        if (i > 0 and A[i] != B[0]) {
            dp[i][0] = dp[i - 1][0];
        }
 
        // If the current character of string A is equal to
        // the first character of string B.
        if (A[i] == B[0]) {
            dp[i][0] = i;
        }
    }
 
    // Iterating through remaining characters of string B.
    for (int j = 1; j < b; ++j) {
 
        // Checking if any character in string A matches
        // with the current character of string B.
        for (int i = 1; i < a; ++i) {
 
            // If there is a match, then starting index of
            // required substring in string 'A' is equal to
            // the starting index when first 'j - 1'
            // characters of string 'B' matched with first
            // 'i - 1' characters of string 'A'.
            if (A[i] == B[j]) {
                dp[i][j] = dp[i - 1][j - 1];
            }
 
            // Else, starting index of required substring in
            // string 'A' is equal to the starting index
            // when first 'j' characters of string 'B'
            // matched with first 'i - 1' characters of
            // string 'A'.
            else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
 
    // String for storing final answer
    string answer = "";
 
    // Length of smallest substring
    int best_length = 1e9;
 
    for (int i = 0; i < a; ++i) {
 
        // dp[i][b-1] is the index in string 'A', such that
        // the substring A(dp[i][b-1] : i) contains string
        // 'B' as a subsequence.
        if (dp[i][b - 1] != -1) {
 
            // Starting index of substring
            int start = dp[i][b - 1];
 
            // Ending index of substring
            int end = i;
 
            // Length of substring
            int current_length = end - start + 1;
 
            // if current length is lesser than the best
            // length update the answer.
            if (current_length < best_length) {
                best_length = current_length;
 
                // Update the answer
                answer = A.substr(start, best_length);
            }
        }
    }
 
    // Return the smallest substring
    return answer;
}
 
// This function is initializing dp with -1
// and printing the result
void smallestSubstringUtil(string& A, string& B)
{
    // Initialize dp array with -1
    memset(dp, -1, sizeof dp);
 
    // Function call
    cout << smallestSubstring(A, B) << endl;
}
 
// Driver code
int main()
{
    // Input strings
    string A = "abcedbaced";
    string B = "bed";
 
    // Function Call
    smallestSubstringUtil(A, B);
 
    return 0;
}


Java
// Java implementation of above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Stores the dp-states
  static int[][] dp = new int[100][100];
 
  // Function to find the smallest subString in String A which
  // contains String B as a subsequence.
  static String smallestSubstring(String A, String B)
  {
     
    // Size of String A
    int a = A.length();
 
    // Size of String B
    int b = B.length();
 
    // Initializing the first column of dp array.
    // Storing the occurence of first character of String B
    // in first (i + 1) characters of String A.
    for (int i = 0; i < a; ++i) {
 
      // If the current character of String A does not
      // match the first character of String B.
      if (i > 0 && A.charAt(i) != B.charAt(0)) {
        dp[i][0] = dp[i - 1][0];
      }
 
      // If the current character of String A is equal to
      // the first character of String B.
      if (A.charAt(i) == B.charAt(0)) {
        dp[i][0] = i;
      }
    }
 
    // Iterating through remaining characters of String B.
    for (int j = 1; j < b; ++j) {
 
      // Checking if any character in String A matches
      // with the current character of String B.
      for (int i = 1; i < a; ++i) {
 
        // If there is a match, then starting index of
        // required subString in String 'A' is equal to
        // the starting index when first 'j - 1'
        // characters of String 'B' matched with first
        // 'i - 1' characters of String 'A'.
        if (A.charAt(i) == B.charAt(j)) {
          dp[i][j] = dp[i - 1][j - 1];
        }
 
        // Else, starting index of required subString in
        // String 'A' is equal to the starting index
        // when first 'j' characters of String 'B'
        // matched with first 'i - 1' characters of
        // String 'A'.
        else {
          dp[i][j] = dp[i - 1][j];
        }
      }
    }
 
    // String for storing final answer
    String answer = "";
 
    // Length of smallest substring
    int best_length = 100000000;
 
    for (int i = 0; i < a; ++i) {
 
      // dp[i][b-1] is the index in String 'A', such that
      // the subString A(dp[i][b-1] : i) contains string
      // 'B' as a subsequence.
      if (dp[i][b - 1] != -1) {
 
        // Starting index of substring
        int start = dp[i][b - 1];
 
        // Ending index of substring
        int end = i;
 
        // Length of substring
        int current_length = end - start + 1;
 
        // if current length is lesser than the best
        // length update the answer.
        if (current_length < best_length) {
          best_length = current_length;
 
          // Update the answer
          answer = A.substring(start, best_length+1);
        }
      }
    }
 
    // Return the smallest substring
    return answer;
  }
 
  // This function is initializing dp with -1
  // and printing the result
  static void smallestSubstringUtil(String A, String B)
  {
    // Initialize dp array with -1
    for(int i=0;i<100;i++)
    {
      for(int j=0;j<100;j++)
      {
        dp[i][j] = -1;
      }
    }
 
    // Function call
    System.out.print( smallestSubstring(A, B) );
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    // Input strings
    String A = "abcedbaced";
    String B = "bed";
 
    // Function Call
    smallestSubstringUtil(A, B);
  }
}
 
// This code is contributed by sanjoy_62.


Python3
# python3 program for the above approach
 
# Stores the dp-states
dp = [[-1 for _ in range(100)] for _ in range(100)]
 
# Function to find the smallest substring in string A which
# contains string B as a subsequence.
def smallestSubstring(A, B):
 
    # Size of string A
    a = len(A)
 
    # Size of string B
    b = len(B)
 
    # Initializing the first column of dp array.
    # Storing the occurence of first character of string B
    # in first (i + 1) characters of string A.
    for i in range(0, a):
 
        # If the current character of string A does not
        # match the first character of string B.
        if (i > 0 and A[i] != B[0]):
            dp[i][0] = dp[i - 1][0]
 
        # If the current character of string A is equal to
        # the first character of string B.
        if (A[i] == B[0]):
            dp[i][0] = i
 
    # Iterating through remaining characters of string B.
    for j in range(1, b):
 
        # Checking if any character in string A matches
        # with the current character of string B.
        for i in range(1, a):
 
            # If there is a match, then starting index of
            # required substring in string 'A' is equal to
            # the starting index when first 'j - 1'
            # characters of string 'B' matched with first
            # 'i - 1' characters of string 'A'.
            if (A[i] == B[j]):
                dp[i][j] = dp[i - 1][j - 1]
 
            # Else, starting index of required substring in
            # string 'A' is equal to the starting index
            # when first 'j' characters of string 'B'
            # matched with first 'i - 1' characters of
            # string 'A'.
            else:
                dp[i][j] = dp[i - 1][j]
 
    # String for storing final answer
    answer = ""
 
    # Length of smallest substring
    best_length = 1e9
 
    for i in range(0, a):
 
        # dp[i][b-1] is the index in string 'A', such that
        # the substring A(dp[i][b-1] : i) contains string
        # 'B' as a subsequence.
        if (dp[i][b - 1] != -1):
 
            # Starting index of substring
            start = dp[i][b - 1]
 
            # Ending index of substring
            end = i
 
            # Length of substring
            current_length = end - start + 1
 
            # if current length is lesser than the best
            # length update the answer.
            if (current_length < best_length):
                best_length = current_length
 
                # Update the answer
                answer = A[start: start + best_length]
 
    # Return the smallest substring
    return answer
 
# This function is initializing dp with -1
# and printing the result
def smallestSubstringUtil(A, B):
 
    # Initialize dp array with -1
 
    # Function call
    print(smallestSubstring(A, B))
 
# Driver code
if __name__ == "__main__":
 
    # Input strings
    A = "abcedbaced"
    B = "bed"
 
    # Function Call
    smallestSubstringUtil(A, B)
 
# This code is contributed by rakeshsahni


C#
// C# program of the above approach
using System;
using System.Linq;
using System.Collections.Generic;
 
class GFG
{
 
  // Stores the dp-states
  static int[,] dp = new int[100, 100];
 
  // Function to find the smallest substring in string A which
  // contains string B as a subsequence.
  static string smallestSubstring(string A, string B)
  {
    // Size of string A
    int a = A.Length;
 
    // Size of string B
    int b = B.Length;
 
    // Initializing the first column of dp array.
    // Storing the occurence of first character of string B
    // in first (i + 1) characters of string A.
    for (int i = 0; i < a; ++i) {
 
      // If the current character of string A does not
      // match the first character of string B.
      if (i > 0 && A[i] != B[0]) {
        dp[i,0] = dp[i - 1, 0];
      }
 
      // If the current character of string A is equal to
      // the first character of string B.
      if (A[i] == B[0]) {
        dp[i,0] = i;
      }
    }
 
    // Iterating through remaining characters of string B.
    for (int j = 1; j < b; ++j) {
 
      // Checking if any character in string A matches
      // with the current character of string B.
      for (int i = 1; i < a; ++i) {
 
        // If there is a match, then starting index of
        // required substring in string 'A' is equal to
        // the starting index when first 'j - 1'
        // characters of string 'B' matched with first
        // 'i - 1' characters of string 'A'.
        if (A[i] == B[j]) {
          dp[i,j] = dp[i - 1,j - 1];
        }
 
        // Else, starting index of required substring in
        // string 'A' is equal to the starting index
        // when first 'j' characters of string 'B'
        // matched with first 'i - 1' characters of
        // string 'A'.
        else {
          dp[i,j] = dp[i - 1,j];
        }
      }
    }
 
    // String for storing final answer
    string answer = "";
 
    // Length of smallest substring
    int best_length = 100000000;
 
    for (int i = 0; i < a; ++i) {
 
      // dp[i][b-1] is the index in string 'A', such that
      // the substring A(dp[i][b-1] : i) contains string
      // 'B' as a subsequence.
      if (dp[i,b - 1] != -1) {
 
        // Starting index of substring
        int start = dp[i,b - 1];
 
        // Ending index of substring
        int end = i;
 
        // Length of substring
        int current_length = end - start + 1;
 
        // if current length is lesser than the best
        // length update the answer.
        if (current_length < best_length) {
          best_length = current_length;
 
          // Update the answer
          answer = A.Substring(start, best_length);
        }
      }
    }
 
    // Return the smallest substring
    return answer;
  }
 
  // This function is initializing dp with -1
  // and printing the result
  static void smallestSubstringUtil(string A, string B)
  {
    // Initialize dp array with -1
    for(int i=0;i<100;i++)
    {
      for(int j=0;j<100;j++)
      {
        dp[i,j] = -1;
      }
    }
 
    // Function call
    Console.Write( smallestSubstring(A, B));
  }
 
  // Driver Code
  public static void Main()
  {
    // Input strings
    string A = "abcedbaced";
    string B = "bed";
 
    // Function Call
    smallestSubstringUtil(A, B);
  }
}
 
// This code is contributed by sanjoy_62.


Javascript



输出
bced

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