给定两个字符串S和T ,任务是从S中找到由字符串T的所有字符组成的最小长度前缀。如果S不包含字符串T 的所有字符,则打印-1 。
例子:
Input: S = “MarvoloGaunt”, T = “Tom”
Output: 12
Explanation:
The 12 length prefix “MarvoloGaunt” contains all the characters of “Tom”
Input: S = “TheWorld”, T = “Dio”
Output: -1
Explanation:
The string “TheWorld” does not contain the character ‘i’ from the string “Dio”.
天真的方法:
解决问题的最简单方法是迭代字符串S并比较前缀和T中每个字母的频率,如果找到所需的前缀,则返回遍历的长度。否则,返回-1。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:
要优化上述方法,请按照以下步骤操作:
- 将T的频率存储在字典dictCount 中。
- 将计数大于 0 的唯一字母的数量存储为nUnique 。
- 迭代[0, N] ,得到S 的第i个索引字符作为ch 。
- 如果存在,则从dictCount 中减少ch的计数。如果此计数变为 0,则将 nUnique 减1。
- 如果nUnique达到 0,则返回到那时遍历的长度。
- 完全遍历S 后,如果nUnique仍然超过 0,则打印-1 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int getPrefixLength(string srcStr,
string targetStr)
{
// Base Case - if T is empty,
// it matches 0 length prefix
if (targetStr.length() == 0)
return 0;
// Convert strings to lower
// case for uniformity
transform(srcStr.begin(),
srcStr.end(),
srcStr.begin(), ::tolower);
transform(targetStr.begin(),
targetStr.end(),
targetStr.begin(), ::tolower);
map dictCount;
int nUnique = 0;
// Update dictCount to the
// letter count of T
for(char ch: targetStr)
{
// If new character is found,
// initialize its entry,
// and increase nUnique
if (dictCount.find(ch) ==
dictCount.end())
{
nUnique += 1;
dictCount[ch] = 0;
}
// Increase count of ch
dictCount[ch] += 1;
}
// Iterate from 0 to N
for(int i = 0; i < srcStr.length(); i++)
{
// i-th character
char ch = srcStr[i];
// Skip if ch not in targetStr
if (dictCount.find(ch) ==
dictCount.end())
continue;
// Decrease Count
dictCount[ch] -= 1;
// If the count of ch reaches 0,
// we do not need more ch,
// and can decrease nUnique
if (dictCount[ch] == 0)
nUnique -= 1;
// If nUnique reaches 0,
// we have found required prefix
if (nUnique == 0)
return (i + 1);
}
// Otherwise
return -1;
}
// Driver code
int main()
{
string S = "MarvoloGaunt";
string T = "Tom";
cout << getPrefixLength(S, T);
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java program for the above approach
import java.util.*;
public class Main
{
public static int getPrefixLength(String srcStr, String targetStr)
{
// Base Case - if T is empty,
// it matches 0 length prefix
if (targetStr.length() == 0)
return 0;
// Convert strings to lower
// case for uniformity
srcStr = srcStr.toLowerCase();
targetStr = targetStr.toLowerCase();
HashMap dictCount = new HashMap<>();
int nUnique = 0;
// Update dictCount to the
// letter count of T
for(char ch : targetStr.toCharArray())
{
// If new character is found,
// initialize its entry,
// and increase nUnique
if (dictCount.containsKey(ch) != true)
{
nUnique += 1;
dictCount.put(ch, 0);
}
// Increase count of ch
dictCount.replace(ch, dictCount.get(ch) + 1);
}
// Iterate from 0 to N
for(int i = 0; i < srcStr.length(); i++)
{
// i-th character
char ch = srcStr.charAt(i);
// Skip if ch not in targetStr
if (dictCount.containsKey(ch) != true)
continue;
// Decrease Count
dictCount.replace(ch, dictCount.get(ch) - 1);
// If the count of ch reaches 0,
// we do not need more ch,
// and can decrease nUnique
if (dictCount.get(ch) == 0)
nUnique -= 1;
// If nUnique reaches 0,
// we have found required prefix
if (nUnique == 0)
return (i + 1);
}
// Otherwise
return -1;
}
// Driver code
public static void main(String[] args) {
String S = "MarvoloGaunt";
String T = "Tom";
System.out.println(getPrefixLength(S, T));
}
}
// This code is contributed by divyesh072019
Python3
# Python3 program for the above approach
def getPrefixLength(srcStr, targetStr):
# Base Case - if T is empty,
# it matches 0 length prefix
if(len(targetStr) == 0):
return 0
# Convert strings to lower
# case for uniformity
srcStr = srcStr.lower()
targetStr = targetStr.lower()
dictCount = dict([])
nUnique = 0
# Update dictCount to the
# letter count of T
for ch in targetStr:
# If new character is found,
# initialize its entry,
# and increase nUnique
if(ch not in dictCount):
nUnique += 1
dictCount[ch] = 0
# Increase count of ch
dictCount[ch] += 1
# Iterate from 0 to N
for i in range(len(srcStr)):
# i-th character
ch = srcStr[i]
# Skip if ch not in targetStr
if(ch not in dictCount):
continue
# Decrease Count
dictCount[ch] -= 1
# If the count of ch reaches 0,
# we do not need more ch,
# and can decrease nUnique
if(dictCount[ch] == 0):
nUnique -= 1
# If nUnique reaches 0,
# we have found required prefix
if(nUnique == 0):
return (i + 1)
# Otherwise
return -1
# Driver Code
if __name__ == "__main__":
S = "MarvoloGaunt"
T = "Tom"
print(getPrefixLength(S, T))
C#
// C# program for the above approach
using System.Collections.Generic;
using System;
class GFG{
static int getPrefixLength(string srcStr,
string targetStr)
{
// Base Case - if T is empty,
// it matches 0 length prefix
if (targetStr.Length == 0)
return 0;
// Convert strings to lower
// case for uniformity
srcStr = srcStr.ToLower();
targetStr = targetStr.ToLower();
Dictionary dictCount = new Dictionary();
int nUnique = 0;
// Update dictCount to the
// letter count of T
foreach(var ch in targetStr)
{
// If new character is found,
// initialize its entry,
// and increase nUnique
if (dictCount.ContainsKey(ch) != true)
{
nUnique += 1;
dictCount[ch] = 0;
}
// Increase count of ch
dictCount[ch] += 1;
}
// Iterate from 0 to N
for(int i = 0; i < srcStr.Length; i++)
{
// i-th character
char ch = srcStr[i];
// Skip if ch not in targetStr
if (dictCount.ContainsKey(ch) != true)
continue;
// Decrease Count
dictCount[ch] -= 1;
// If the count of ch reaches 0,
// we do not need more ch,
// and can decrease nUnique
if (dictCount[ch] == 0)
nUnique -= 1;
// If nUnique reaches 0,
// we have found required prefix
if (nUnique == 0)
return (i + 1);
}
// Otherwise
return -1;
}
// Driver code
public static void Main()
{
string S = "MarvoloGaunt";
string T = "Tom";
Console.Write(getPrefixLength(S, T));
}
}
// This code is contributed by Stream_Cipher
Javascript
输出:
12
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。