给定两个字符串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中每个字符的频率存储在数组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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live