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

📅  最后修改于: 2021-04-29 09:31:31             🧑  作者: Mango

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

例子:

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

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

下面是上述方法的实现:

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)