Open In App

Find whether X exists in Y after jumbling X

Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings X and Y containing lower-case alphabets, the task is to check whether any permutation of string X exists in Y as its substring.

Examples: 

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  

Approach: This problem can be solved using the two pointer technique.

  • Compute the frequency count of every character of string X and store it in an array say cnt_X[].
  • Now for substring Y[i…(i+X.length()-1)], the same frequency array can be generated say cnt[].
  • Using the array from step 2, the frequency count for the next window can be calculated in O(1) time by decrementing cnt[Y[i] – ‘a’] by 1 and incrementing cnt[Y[i + X.length()] – ‘a’] by 1.
  • Compare cnt[] and cnt_X[] for every window. If both of them are equal then a match has been found.

Below is the implementation of the above approach: 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
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


Javascript




<script>
 
// Javascript implementation of the approach
 
var MAX = 26;
 
// Function that returns true if both
// the arrays have equal values
function areEqual(a, b)
{
    // Test the equality
    for (var 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
function xExistsInY(x, y)
{
 
    // Base case
    if (x.length > y.length)
        return false;
 
    // To store cumulative frequency
    var cnt_x = Array(MAX).fill(0);
    var cnt = Array(MAX).fill(0);
 
    // Finding the frequency of
    // characters in X
    for (var i = 0; i < x.length; i++)
        cnt_x[x[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
    // Finding the frequency of characters
    // in Y upto the length of X
    for (var i = 0; i < x.length; i++)
        cnt[y[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
    // Equality check
    if (areEqual(cnt_x, cnt))
        return true;
 
    // Two pointer approach to generate the
    // entire cumulative frequency
    for (var i = 1; i < y.length - x.length + 1; i++) {
 
        // Remove the first character of
        // the previous window
        cnt[y[i - 1].charCodeAt(0) - 'a'.charCodeAt(0)]--;
 
        // Add the last character of
        // the current window
        cnt[y[i + x.length - 1].charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
        // Equality check
        if (areEqual(cnt, cnt_x))
            return true;
    }
 
    return false;
}
 
// Driver code
var x = "skege";
var y = "geeksforgeeks";
if (xExistsInY(x, y))
    document.write( "Yes");
else
    document.write("No");
 
</script>


Output: 

Yes

 

Time Complexity: O(xLen + yLen) where xLen and yLen are the lengths of the strings X and Y respectively.
Auxiliary Space: O(1), no extra space is required, so it is a constant.



Last Updated : 28 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads