📌  相关文章
📜  检查字符串S可以通过附加字符串S1的子序列来获得

📅  最后修改于: 2021-10-25 06:50:42             🧑  作者: Mango

给定两个字符串S1S2 ,任务是检查是否可以通过将S1 的子序列重复附加到初始空字符串的末尾来生成字符串S2 。如果可能,打印“”和所需的最少操作次数。否则,打印“ NO ”。

例子:

处理方法:按照以下步骤解决问题:

  • 迭代字符串S1 的字符并将S1中每个字符的频率存储在数组freq[] 中
  • 遍历字符串S2并检查 S2 中是否存在 S1 中不存在的任何字符。如果发现任何这样的字符,打印“NO”。
  • 否则,迭代S1 中的字符并更新 Set 中每个字符的索引
  • 遍历字符串S2并对每个字符,检查它是否可以包含在可以追加的S1的当前子序列中。
  • 如果发现为真,则将当前字符的索引设置为附加的最后一个字符的索引。否则,增加子序列的计数并将当前字符的索引设置为附加的最后一个字符的索引。继续下一个字符。
  • 最后,打印“ YES ”和此类子序列的计数作为所需答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include "bits/stdc++.h"
using namespace std;
 
// Function for finding minimum
// number of operations
int findMinimumOperations(string s,
                          string s1)
{
 
    // Stores the length of strings
    int n = s.length(), m = s1.length();
 
    // Stores frequency of
    // characters in string s
    int frequency[26] = { 0 };
 
    // Update  frequencies of
    // character in s
    for (int i = 0; i < n; i++)
        frequency[s[i] - 'a']++;
 
    // Traverse string s1
    for (int i = 0; i < m; i++) {
 
        // If any character in s1
        // is not present in s
        if (frequency[s1[i] - 'a']
            == 0) {
            return -1;
        }
    }
 
    // Stores the indices of
    // each character in s
    set indices[26];
 
    // Traverse string s
    for (int i = 0; i < n; i++) {
 
        // Store indices of characters
        indices[s[i] - 'a'].insert(i);
    }
 
    int ans = 1;
 
    // Stores index of last
    // appended characterr
    int last = (*indices[s1[0]
                      - 'a']
                     .begin());
 
    // Traaverse string s1
    for (int i = 1; i < m; i++) {
 
        int ch = s1[i] - 'a';
 
        // Find the index of next
        // character that can be appended
        auto it = indices[ch].upper_bound(
            last);
 
        // Check if the current
        // character be included
        // in the current subsequence
        if (it != indices[ch].end()) {
            last = (*it);
        }
 
        // Otherwise
        else {
 
            // Start a new subsequence
            ans++;
 
            // Update index of last
            // character appended
            last = (*indices[ch].begin());
        }
    }
    return ans;
}
 
// Driver Code
int main()
{
 
    string S1 = "acebcd", S2 = "acbcde";
    int ans = findMinimumOperations(
        S1, S2);
 
    // If S2 cannot be obtained
    // from subsequences of S1
    if (ans == -1) {
        cout << "NO\n";
    }
    // Otherwise
    else {
        cout << "YES\n"
             << ans;
    }
 
    return 0;
}


Python3
# Python3 Program to implement
# the above approach
from bisect import bisect ,bisect_left,bisect_right
 
# Function for finding minimum
# number of operations
def findMinimumOperations(s,s1):
 
    #Stores the length of strings
    n = len(s)
    m = len(s1)
 
    # Stores frequency of
    # characters in string s
    frequency = [0]*26
 
    # Update  frequencies of
    # character in s
    for i in range(n):
        frequency[ord(s[i]) - ord('a')] += 1
 
    # Traverse string s1
    for i in range(m):
 
        # If any character in s1
        # is not present in s
        if (frequency[ord(s1[i]) - ord('a')] == 0):
            return -1
 
    # Stores the indices of
    # each character in s
    indices = [[] for i in range(26)]
 
    # Traverse string s
    for i in range(n):
 
        # Store indices of characters
        indices[ord(s[i]) - ord('a')].append(i)
 
    ans = 2
 
    # Stores index of last
    # appended characterr
    last =len(indices[ord(s1[0])- ord('a')]) - 1
 
    # Traaverse string s1
    for i in range(1,m):
 
        ch = ord(s1[i]) - ord('a')
 
        # Find the index of next
        # character that can be appended
        it = bisect_right(indices[ch],last)
        # print(it)
 
        # Check if the current
        # character be included
        # in the current subsequence
        if (it != len(indices[ch])):
            last = it
        # Otherwise
        else:
 
            # Start a new subsequence
            ans += 1
 
            # Update index of last
            # character appended
            last = len(indices[ch])
    return ans
 
# Driver Code
if __name__ == '__main__':
 
    S1 = "acebcd"
    S2 = "acbcde"
    ans = findMinimumOperations(S1, S2)
 
    # If S2 cannot be obtained
    # from subsequences of S1
    if (ans == -1):
        print("NO")
    # Otherwise
    else:
        print("YES")
        print(ans)
 
# This code is contributed by mohit kumar 29


输出:
YES
2

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程