获取字符串 B 所需的字符串 A 的最小子序列数
在这个问题中,我们需要使用 str1 的子序列来构造 str2。为了解决这个问题,我们可以找到 str1 的子序列,以便它可以覆盖 str2 的最大长度子字符串。在这里,我们将学习两种不同的解决问题的方法。
问题陈述 – 我们得到了两个字符串,str1 和 str2,它们具有不同的长度。我们需要按照以下条件从 str1 构造 str2。
从 str1 中选择任何子序列,并将其追加到最初为空的新字符串中。
我们需要返回构建 str2 所需的最少操作次数,或者如果无法构建 str2,则打印 -1。
示例
输入 – str1 = "acd", str2 = "adc"
输出– 2
解释
来自 str1 的第一个子序列是“ad”。因此,我们的字符串可以是“ad”。
之后,我们可以从 str1 中获取子序列“c”,并将其追加到“ad”以使其成为“adc”。
输入– str1 = "adcb", str2 = "abdca"
输出– 3
解释
第一个子序列是来自 str1 的“ab”。
之后,我们可以获取字符串“dc”,结果字符串将为“abdc”
接下来,我们可以获取子序列“a”以形成最终字符串“abdca”。
方法 1
在这种方法中,我们将迭代 str1 以查找多个子序列并将其追加到结果字符串。
算法
定义长度为 26 的“arr”数组,并将所有元素初始化为 0 以存储 str1 中字符的存在。
遍历 str1,并根据字符的 ASCII 值更新数组元素的值
定义“last”变量并初始化为 -1 以跟踪上次访问的元素。此外,定义“cnt”变量并将其初始化为 0 以存储操作计数。
使用循环开始遍历 str2。
如果 str1 中不存在当前字符,则返回 -1。
将“j”变量初始化为“last + 1”的值。
使用 while 循环进行迭代,直到“j”的值小于 len,并且 str1[j] 不等于字符
如果“j”的值大于“len”,我们将遍历“str1”。增加“cnt”变量的值,将“last”初始化为 -1(因为我们需要再次遍历“str1”),将“I”的值减 1(因为我们需要再次考虑当前字符),使用“continue”关键字继续迭代。
将“last”变量的值更新为“j”。
一旦循环的所有迭代完成,返回“cnt + 1”。在这里,我们需要将“1”添加到“cnt”,因为我们没有考虑最后一次操作。
示例
#include <iostream>
using namespace std;
// function to count the minimum number of operations required to get string str2 from subsequences of string str1.
int minOperations(string str1, string str2){
int len = str1.length();
// creating an array of size 26 to store the presence of characters in string str1.
int arr[26] = {0};
// storing the presence of characters in string str1.
for (int i = 0; i < len; i++){
arr[str1[i] - 'a']++;
}
// store the last iterated index of string str1.
int last = -1;
// to store the count of operations.
int cnt = 0;
for (int i = 0; i < str2.length(); i++){
char ch = str2[i];
// if the character is not present in string str1, then return -1.
if (arr[ch - 'a'] == 0){
return -1;
}
// start iterating from the jth index of string str1 to find the character ch.
int j = last + 1;
while (j < len && str1[j] != ch){
j++;
}
// if j is equal to the length of string str1, then increment the count, set last to -1, and decrement i.
if (j >= len){
cnt++;
last = -1;
--i;
continue;
}
// set last to j.
last = j;
}
// return cnt + 1 as we haven't counted the last operation.
return cnt + 1;
}
int main(){
string str1 = "acd", str2 = "adc";
int operations = minOperations(str1, str2);
cout << "Minimum number of operations required to create string B from the subsequences of the string A is: " << operations << "\n";
return 0;
}
输出
Minimum number of operations required to create string B from the subsequences of the string A is: 2
时间复杂度 – O(N*M),其中 N 是 str2 的长度,M 是 str1 的长度。
空间复杂度 – O(1),因为我们没有使用任何动态空间。
方法 2
在这种方法中,我们将使用 map 和 set 数据结构来提高上述方法的效率。解决问题的逻辑将与上述方法相同。
算法
定义“chars_mp”以将 char -> set{} 存储为键值对。
在 map 中,存储 str1 字符串中特定字符存在的索引集
定义“last”和“cnt”变量
开始遍历 str2。如果包含当前字符索引的集合的大小为零,则返回 -1。
在当前字符的索引集中查找“last”的上限。
如果未找到上限,则将“cnt”的值增加 1,将“last”设置为 -1,将“I”的值减 1,并使用 continue 关键字。
更新“last”变量的值。
当循环迭代完成后,返回“cnt”变量的值
示例
#include <iostream>
#include <map>
#include <set>
using namespace std;
// function to count the minimum number of operations required to get string str2 from subsequences of string str1.
int minOperations(string str1, string str2){
// Length of string str1
int len = str1.length();
// creating the map to store the set of indices for each character in str1
map<char, set<int>> chars_mp;
// Iterate over the characters of str1 and store the indices of each character in the map
for (int i = 0; i < len; i++){
chars_mp[str1[i]].insert(i);
}
// store the last visited index of str1
int last = -1;
// Stores the required count
int cnt = 1;
// Iterate over the characters of str2
for (int i = 0; i < str2.length(); i++){
char ch = str2[i];
// If the set of indices of str2[i] is empty, then return -1
if (chars_mp[ch].size() == 0){
return -1;
}
// If the set of indices of str2[i] is not empty, then find the upper bound of last in the set of indices of str2[i]
// It finds the smallest index of str2[i] which is greater than last
auto it = chars_mp[ch].upper_bound(last);
// If the upper bound is equal to the end of the set, then increment the count and update last to -1
if (it == chars_mp[ch].end()){
last = -1;
cnt++;
// Decrement I by 1 to process the current character again
--i;
continue;
}
// Update last to the current index
last = *it;
}
return cnt;
}
int main(){
string str1 = "adcb", str2 = "abdca";
int operations = minOperations(str1, str2);
cout << "Minimum number of operations required to create string B from the subsequences of the string A is: " << operations << "\n";
return 0;
}
输出
Minimum number of operations required to create string B from the subsequences of the string A is: 3
时间复杂度 – O(N*logN),因为我们遍历 str2 并查找循环中“last”索引的上限。
空间复杂度 – O(N),因为我们使用 map 来存储字符的索引。
数据结构
网络
RDBMS
操作系统
Java
iOS
HTML
CSS
Android
Python
C 语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP