给定两个包含小写字母的字符串X和Y ,任务是检查字符串X是否作为其子字符串存在于Y中。
例子:
Input: X = “skege”, Y = “geeksforgeeks”
Output: Yes
“geeks” is a permutation of X which
appears as a substring in Y.
Input: X = “aabb”, Y = “bbbbbbb”
Output: No
方法:可以使用两个指针技术解决此问题。
- 计算字符串X的每个字符的频率计数,并将其存储在数组cnt_X []中。
- 现在,对于子字符串Y [i…(i + X.length()-1)] ,可以使用cnt []生成相同的频率数组。
- 使用第2步中的数组,可以通过将cnt [Y [i] –’a ‘]减1并增加cnt [Y [i + X.length( )] –’a’]之前的1 。
- 比较每个窗口的cnt []和cnt_X [] 。如果两者相等,则找到匹配项。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
const int MAX = 26;
// Function that returns true if both
// the arrays have equal values
bool areEqual(int* a, int* b)
{
// Test the equality
for (int i = 0; i < MAX; i++)
if (a[i] != b[i])
return false;
return true;
}
// Function that returns true if any permutation
// of X exists as a substring in Y
bool xExistsInY(string x, string y)
{
// Base case
if (x.size() > y.size())
return false;
// To store cumulative frequency
int cnt_x[MAX] = { 0 };
int cnt[MAX] = { 0 };
// Finding the frequency of
// characters in X
for (int i = 0; i < x.size(); i++)
cnt_x[x[i] - 'a']++;
// Finding the frequency of characters
// in Y upto the length of X
for (int i = 0; i < x.size(); i++)
cnt[y[i] - 'a']++;
// Equality check
if (areEqual(cnt_x, cnt))
return true;
// Two pointer approach to generate the
// entire cumulative frequency
for (int i = 1; i < y.size() - x.size() + 1; i++) {
// Remove the first character of
// the previous window
cnt[y[i - 1] - 'a']--;
// Add the last character of
// the current window
cnt[y[i + x.size() - 1] - 'a']++;
// Equality check
if (areEqual(cnt, cnt_x))
return true;
}
return false;
}
// Driver code
int main()
{
string x = "skege";
string y = "geeksforgeeks";
if (xExistsInY(x, y))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static int MAX = 26;
// Function that returns true if both
// the arrays have equal values
static boolean areEqual(int []a, int []b)
{
// Test the equality
for (int i = 0; i < MAX; i++)
if (a[i] != b[i])
return false;
return true;
}
// Function that returns true if
// any permutation of X exists
// as a subString in Y
static boolean xExistsInY(String x, String y)
{
// Base case
if (x.length() > y.length())
return false;
// To store cumulative frequency
int []cnt_x = new int[MAX];
int []cnt = new int[MAX];
// Finding the frequency of
// characters in X
for (int i = 0; i < x.length(); i++)
cnt_x[x.charAt(i) - 'a']++;
// Finding the frequency of characters
// in Y upto the length of X
for (int i = 0; i < x.length(); i++)
cnt[y.charAt(i) - 'a']++;
// Equality check
if (areEqual(cnt_x, cnt))
return true;
// Two pointer approach to generate the
// entire cumulative frequency
for (int i = 1; i < y.length() -
x.length() + 1; i++)
{
// Remove the first character of
// the previous window
cnt[y.charAt(i - 1) - 'a']--;
// Add the last character of
// the current window
cnt[y.charAt(i + x.length() - 1) - 'a']++;
// Equality check
if (areEqual(cnt, cnt_x))
return true;
}
return false;
}
// Driver code
public static void main(String[] args)
{
String x = "skege";
String y = "geeksforgeeks";
if (xExistsInY(x, y))
System.out.print("Yes");
else
System.out.print("No");
}
}
// This code contributed by PrinciRaj1992
Python3
# Python3 implementation of the approach
MAX = 26
# Function that returns true if both
# the arrays have equal values
def areEqual(a, b):
# Test the equality
for i in range(MAX):
if (a[i] != b[i]):
return False
return True
# Function that returns true if any permutation
# of X exists as a sub in Y
def xExistsInY(x,y):
# Base case
if (len(x) > len(y)):
return False
# To store cumulative frequency
cnt_x = [0] * MAX
cnt = [0] * MAX
# Finding the frequency of
# characters in X
for i in range(len(x)):
cnt_x[ord(x[i]) - ord('a')] += 1;
# Finding the frequency of characters
# in Y upto the length of X
for i in range(len(x)):
cnt[ord(y[i]) - ord('a')] += 1
# Equality check
if (areEqual(cnt_x, cnt)):
return True
# Two pointer approach to generate the
# entire cumulative frequency
for i in range(1, len(y) - len(x) + 1):
# Remove the first character of
# the previous window
cnt[ord(y[i - 1]) - ord('a')] -= 1
# Add the last character of
# the current window
cnt[ord(y[i + len(x) - 1]) - ord('a')] += 1
# Equality check
if (areEqual(cnt, cnt_x)):
return True
return False
# Driver Code
if __name__ == '__main__':
x = "skege"
y = "geeksforgeeks"
if (xExistsInY(x, y)):
print("Yes")
else:
print("No")
# This code is contributed by Mohit Kumar
C#
// C# implementation of the approach
using System;
class GFG
{
static int MAX = 26;
// Function that returns true if both
// the arrays have equal values
static bool areEqual(int []a,
int []b)
{
// Test the equality
for (int i = 0; i < MAX; i++)
if (a[i] != b[i])
return false;
return true;
}
// Function that returns true if
// any permutation of X exists
// as a subString in Y
static bool xExistsInY(String x,
String y)
{
// Base case
if (x.Length > y.Length)
return false;
// To store cumulative frequency
int []cnt_x = new int[MAX];
int []cnt = new int[MAX];
// Finding the frequency of
// characters in X
for (int i = 0; i < x.Length; i++)
cnt_x[x[i] - 'a']++;
// Finding the frequency of characters
// in Y upto the length of X
for (int i = 0; i < x.Length; i++)
cnt[y[i] - 'a']++;
// Equality check
if (areEqual(cnt_x, cnt))
return true;
// Two pointer approach to generate the
// entire cumulative frequency
for (int i = 1; i < y.Length -
x.Length + 1; i++)
{
// Remove the first character of
// the previous window
cnt[y[i - 1] - 'a']--;
// Add the last character of
// the current window
cnt[y[i + x.Length - 1] - 'a']++;
// Equality check
if (areEqual(cnt, cnt_x))
return true;
}
return false;
}
// Driver code
public static void Main(String[] args)
{
String x = "skege";
String y = "geeksforgeeks";
if (xExistsInY(x, y))
Console.Write("Yes");
else
Console.Write("No");
}
}
// This code is contributed by PrinciRaj1992
输出:
Yes
时间复杂度: O(xLen + yLen),其中xLen和yLen分别是字符串X和Y的长度。