给定两个字符串S1和S2 ,任务是检查是否有可能通过将S1的子序列重复添加到最初为空的字符串的末尾来生成字符串S2 。如果可能,打印“是”和所需的最少操作数。否则,打印“ NO ”。
例子:
Input: S1 = “acebcd”, S2 = “acbcd”
Output:
YES
2
Explanation: Append subsequence “acbc” followed by “d” to obtain S2.
Input: S1 = “aceasd”, S2 = “asdxds”
Output: NO
Explanation: Since character ‘x’ is not present in S1, S2 cannot be obtained.
方法:请按照以下步骤解决问题:
- 遍历在阵列频率字符串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)