给定两个分别具有长度N和M的字符串str1和str2 ,任务是检查是否可以通过多次附加str1的子序列来形成str2 。如果可能,请打印所需的最少附加操作数。否则,打印-1 。
例子:
Input: str1 = “abb”, str2 = “ababbbbb”
Output: 4
Explanation:
String str2 can be formed by appending subsequences of str1 = “ab” + “abb” + “bb” + “b” = “ababbbbb”. Since at least 4 operations are required, print 4.
Input: str1 = “mt”, str2 = “atttm”
Output: -1
Explanation:
Since ‘a’ is not present in the string str1, str2 cannot be generated from str1. Therefore, print -1.
方法:该想法是基于以下观察结果使用散列的概念:
- 考虑字符串str1 =“ abb”和str2 =“ aba” 。查找字符str2 [0]在str1中的位置,该字符的索引大于或等于0,即str1的索引0 。
- 同样,在str1中找到str2 [1] ,使其索引大于或等于1,即str1的索引1 。
- 然后,在str1中找到str2 [2] ,使其索引大于或等于2 (不存在)。
- 因此,再次从索引0开始,在str1中找到具有大于或等于索引0的索引,即str1的索引0的str2 [2] 。
- 因此,可以附加两个子序列“ ab”和“ a”以形成“ aba” 。
请按照以下步骤解决问题:
- 初始化长度为26的向量vec []的数组。
- 将所有具有字符‘a’的索引str1推入vec [0] 。同样,在vec [1]中推送所有字符‘b’的索引。对从‘a’到‘z’的每个字符执行此操作。
- 用1初始化一个变量结果,用0初始化position,以存储最小操作数和str1的当前位置。
- 在[0,M]范围内遍历字符串str2 ,并对每个字符执行以下操作:
- 如果VEC [STR2 [I] – ‘A’]是空的,则字符STR2 [i]是不存在于STR1。因此,答案是不可能的。因此,打印-1 。
- 否则,在vec [str2 [i] –’a’]中找到位置的下限。设为p 。如果p等于vec [str2 [i] –’a’]的大小,则将结果加1 ,将i减1,因为尚未找到字符str2 [i]的答案并将位置设置为0 。
- 否则,将位置设置为(vec [p] + 1) 。
- 遍历后,将结果打印为所需的最少操作。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find minimum operations
// required to form str2 by adding
// subsequences of str1
void find(string str1, string str2)
{
// Initialize vector of length 26
vector vec1[26];
// Push indices of characters of str1
for (int i = 0; i < str1.size(); i++)
vec1[str1[i] - 'a'].push_back(i);
// Initialize the result & position
int result = 1, position = 0;
// Traverse the string str2
for (int i = 0; i < str2.size(); i++)
{
char c = str2[i];
// Return if no answer exist
if (vec1.empty())
{
result = -1;
break;
}
// Pointer of vec1[c-'a']
vector& vec2 = vec1;
// Lower bound of position
int p = lower_bound(vec2.begin(),
vec2.end(),
position)
- vec2.begin();
// If no index found
if (p == vec2.size())
{
// Increment result
result++;
i--;
position = 0;
continue;
}
// Update the position
else {
position = vec2[p] + 1;
}
}
// Print the result
cout << result << '\n';
}
// Driver Code
int main()
{
// Given string str1 & str2
string str1 = "abb", str2 = "ababbbbb";
// Function Call
find(str1, str2);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
static void find(String str1, String str2)
{
List > vec1
= new ArrayList >();
// Initialize vector of length 26
for (int i = 0; i < 26; i++) {
vec1.add(new ArrayList());
}
// Push indices of characters of str1
for (int i = 0; i < str1.length(); i++)
vec1.get(str1.charAt(i) - 'a').add(i);
// Initialize the result & position
int result = 1, position = 0;
// Traverse the string str2
for (int i = 0; i < str2.length(); i++)
{
char c = str2.charAt(i);
// Return if no answer exist
if (vec1.get(c - 'a').size() == 0)
{
result = -1;
break;
}
List vec2 = vec1.get(c - 'a');
// Lower bound of position
int p = lower_bound(vec2, position);
// If no index found
if (p == vec2.size())
{
// Increment result
result++;
i--;
position = 0;
continue;
}
// Update the position
else {
position = vec2.get(p) + 1;
}
}
// Print the result
System.out.println(result);
}
// Driver Code
static int lower_bound(List vec2, int position)
{
int low = 0, high = vec2.size() - 1;
while (low < high) {
int mid = (low + high) / 2;
if (vec2.get(mid) < position)
low = mid + 1;
else
high = mid;
}
return (vec2.get(low) < position) ? low + 1 : low;
}
public static void main(String[] args)
{
// Given string str1 & str2
String str1 = "abb", str2 = "ababbbbb";
// Function Call
find(str1, str2);
}
}
Python3
# Python3 program for the above approach
from bisect import bisect_left
# Function to find minimum operations
# required to form str2 by adding
# subsequences of str1
def find(str1, str2):
# Initialize vector of length 26
vec1 = [[] for i in range(26)]
# Push indices of characters of str1
for i in range(len(str1)):
vec1[ord(str1[i]) - ord('a')].append(i)
# Initialize the result & position
result = 1
position = 0
# Traverse the str2
i = 0
while i < len(str2):
c = str2[i]
# Return if no answer exist
if (len(vec1[ord(c) - ord('a')]) == 0):
result = -1
break
# Pointer of vec1[c-'a']
vec2 = vec1[ord(c) - ord('a')]
# Lower bound of position
p = bisect_left(vec2, position)
#print(c)
# If no index found
if (p == len(vec2)):
# Increment result
result += 1
#i-=1
position = 0
continue
# Update the position
else:
i += 1
position = vec2[p] + 1
# Print the result
print(result)
# Driver Code
if __name__ == '__main__':
# Given str1 & str2
str1 = "abb"
str2 = "ababbbbb"
# Function Call
find(str1, str2)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find minimum operations
// required to form str2 by adding
// subsequences of str1
static void find(string str1, string str2)
{
List> vec1 = new List>();
// Initialize vector of length 26
for(int i = 0; i < 26; i++)
{
vec1.Add(new List());
}
// Push indices of characters of str1
for(int i = 0; i < str1.Length; i++)
{
vec1[str1[i] - 'a'].Add(i);
}
// Initialize the result & position
int result = 1, position = 0;
// Traverse the string str2
for(int i = 0; i < str2.Length; i++)
{
char c = str2[i];
// Return if no answer exist
if (vec1.Count == 0)
{
result = -1;
break;
}
List vec2 = vec1;
// Lower bound of position
int p = lower_bound(vec2, position);
// If no index found
if (p == vec2.Count)
{
// Increment result
result++;
i--;
position = 0;
continue;
}
// Update the position
else
{
position = vec2[p] + 1;
}
}
// Print the result
Console.WriteLine(result);
}
static int lower_bound(List vec2,
int position)
{
int low = 0, high = vec2.Count - 1;
while (low < high)
{
int mid = (low + high) / 2;
if (vec2[mid] < position)
{
low = mid + 1;
}
else
{
high = mid;
}
}
return (vec2[low] < position) ?
low + 1 : low;
}
// Driver Code
static public void Main()
{
// Given string str1 & str2
string str1 = "abb", str2 = "ababbbbb";
// Function Call
find(str1, str2);
}
}
// This code is contributed by avanitrachhadiya2155
输出
4
时间复杂度: O(N + M log N)
辅助空间: O(M + N)