Open In App

Checking valid shuffle of two Strings

Last Updated : 13 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings str1 and str2, and a third-string shuffle, determine if shuffle is a valid shuffle of str1 and str2, where a valid shuffle contains all characters from str1 and str2 occurring the same number of times, regardless of order. Print “YES” if valid, and “NO” otherwise.

Examples: 

Input: str1 = BA, str2 = XY, shuffle = XYAB 
Output: YES

Input: str1 = BA, str2 = XY, shuffle = XUMB 
Output: NO

Input: str1 = ABC, str2 = ZYS, shuffle = YBAZSC 
Output:YES

Approach: To solve the problem follow the below idea:

The simplest approach that comes to mind is when we observe the given inputs carefully, we see that we only need to check if the frequency of each character in the string shuffle is exactly as it is in both the str1 and str2 and also the length should be of the length of str1 + length of str2. So, we can use a hashmap here.

Follow the steps to solve the problem:

  • Create a hashmap
  • Store the count of each character in both the given strings inside the hashmap
  • Now, traverse on the string ‘shuffle’. And for every character encountered in string shuffle, look for it inside the hashmap. 
    • If the character is found then keep traversing till we reach the end of the substring and do the same for each character and decrease the frequency for each character that we come across. 
    • If any character isn’t found in the hashmap, then return false.

Below is the implementation for the above approach:

C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;

bool validShuffle(string str1, string str2, string shuffle)
{

    // n1 = size of str1, n2 = size of str2
    int n1 = str1.size();
    int n2 = str2.size();

    // n = size of string shuffle
    int n = shuffle.size();

    // Its obvious if the no. of char in
    // shuffle are more or less than the
    // length of str1 and str2 then it
    // won't be a valid shuffle
    if (n != n1 + n2)
        return false;

    // We use an unordered map to keep
    // track of frequency of
    // each character.
    unordered_map<int, int> freq;

    // Count frequency of each char
    // in str1
    for (int i = 0; i < n1; i++)
        freq[str1[i]]++;

    // Count frequency of each char
    // in str2
    for (int i = 0; i < n2; i++)
        freq[str2[i]]++;

    // If any of the char is not found in
    // the map, then its not a
    // valid shuffle.
    for (int i = 0; i < n; i++) {
        if (freq.find(shuffle[i]) != freq.end())
            freq[shuffle[i]]--;
        else
            return false;
    }

    // Checks whether all the elements's frequency in
    // hashmap becomes 0
    for (auto it : freq) {
        if (it.second != 0) {
            return false;
        }
    }
    return true;
}

// Drivers code
int main()
{
    string str1 = "BA", str2 = "XY", shuffle = "ABYX";

    (validShuffle(str1, str2, shuffle) == true)
        ? printf("YES")
        : printf("NO");
    cout << endl;

    return 0;
}

// This code is modified by Susobhan Akhuli
Java
import java.util.HashMap;
import java.util.Map;
// Nikunj Sonigara

public class GFG {
    static boolean validShuffle(String str1, String str2,
                                String shuffle)
    {
        int n1 = str1.length();
        int n2 = str2.length();
        int n = shuffle.length();

        if (n != n1 + n2) {
            return false;
        }

        HashMap<Character, Integer> freq = new HashMap<>();

        for (int i = 0; i < n1; i++) {
            freq.put(str1.charAt(i),
                     freq.getOrDefault(str1.charAt(i), 0)
                         + 1);
        }

        for (int i = 0; i < n2; i++) {
            freq.put(str2.charAt(i),
                     freq.getOrDefault(str2.charAt(i), 0)
                         + 1);
        }

        for (int i = 0; i < n; i++) {
            if (freq.containsKey(shuffle.charAt(i))) {
                freq.put(shuffle.charAt(i),
                         freq.get(shuffle.charAt(i)) - 1);
            }
            else {
                return false;
            }
        }

        // Checks whether all the elements's frequency in
        // hashmap becomes 0
        for (Map.Entry<Character, Integer> entry :
             freq.entrySet()) {
            if (entry.getValue() != 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args)
    {
        String str1 = "BA";
        String str2 = "XY";
        String shuffle = "ABYX";

        if (validShuffle(str1, str2, shuffle)) {
            System.out.println("YES");
        }
        else {
            System.out.println("NO");
        }
    }
}

// This code is modified by Susobhan Akhuli
Python3
def validShuffle(str1, str2, shuffle):
    n1 = len(str1)
    n2 = len(str2)
    n = len(shuffle)
    
    if n != n1 + n2:
        return False
    
    freq = {}
    
    for i in range(n1):
        if str1[i] in freq:
            freq[str1[i]] += 1
        else:
            freq[str1[i]] = 1
    
    for i in range(n2):
        if str2[i] in freq:
            freq[str2[i]] += 1
        else:
            freq[str2[i]] = 1
    
    for i in range(n):
        if shuffle[i] in freq:
            freq[shuffle[i]] -= 1
        else:
            return False
        
    # Checks whether all the elements's frequency becomes 0
    for key, value in freq.items():
        if(value != 0):
            return False
    return True

str1 = "BA"
str2 = "XY"
shuffle = "ABYX"

if validShuffle(str1, str2, shuffle):
    print("YES")
else:
    print("NO")

# This code is modified by Susobhan Akhuli
C#
using System;
using System.Collections.Generic;

class Program {
    static bool ValidShuffle(string str1, string str2,
                             string shuffle)
    {
        // n1 = size of str1, n2 = size of str2
        int n1 = str1.Length;
        int n2 = str2.Length;

        // n = size of string shuffle
        int n = shuffle.Length;

        // Its obvious if the no. of char in
        // shuffle are more or less than the
        // length of str1 and str2 then it
        // won't be a valid shuffle
        if (n != n1 + n2) {
            return false;
        }

        // We use an unordered map to keep
        // track of frequency of
        // each character.
        Dictionary<char, int> freq
            = new Dictionary<char, int>();

        // Count frequency of each char
        // in str1
        for (int i = 0; i < n1; i++) {
            if (freq.ContainsKey(str1[i])) {
                freq[str1[i]] += 1;
            }
            else {
                freq[str1[i]] = 1;
            }
        }

        // Count frequency of each char
        // in str2
        for (int i = 0; i < n2; i++) {
            if (freq.ContainsKey(str2[i])) {
                freq[str2[i]] += 1;
            }
            else {
                freq[str2[i]] = 1;
            }
        }

        // If any of the char is not found in
        // the map, then its not a
        // valid shuffle.
        for (int i = 0; i < n; i++) {
            if (freq.ContainsKey(shuffle[i])) {
                freq[shuffle[i]] -= 1;
            }
            else {
                return false;
            }
        }

        // Checks whether all the elements's frequency in
        // hashmap becomes 0
        foreach(int value in freq.Values)
        {
            if (value != 0) {
                return false;
            }
        }
        return true;
    }

    // Drivers code
    static void Main(string[] args)
    {
        string str1 = "BA";
        string str2 = "XY";
        string shuffle = "ABYX";
        if (ValidShuffle(str1, str2, shuffle)) {
            Console.WriteLine("YES");
        }
        else {
            Console.WriteLine("NO");
        }
    }
}

// This code is modified by Susobhan Akhuli
Javascript
function validShuffle(str1, str2, shuffle) {
    const n1 = str1.length;
    const n2 = str2.length;
    const n = shuffle.length;

    if (n !== n1 + n2)
        return false;

    const freq = new Map();

    for (let i = 0; i < n1; i++)
        freq.set(str1[i], (freq.get(str1[i]) || 0) + 1);

    for (let i = 0; i < n2; i++)
        freq.set(str2[i], (freq.get(str2[i]) || 0) + 1);

    for (let i = 0; i < n; i++) {
        if (freq.has(shuffle[i]))
            freq.set(shuffle[i], freq.get(shuffle[i]) - 1);
        else
            return false;
    }
    
    // Checks whether all the elements's frequency becomes 0
    for (let [key, value] of freq) {
        if (value != 0) {
            return false;
        }
    }
    return true;
}

const str1 = "BA";
const str2 = "XY";
const shuffle = "ABYX";
console.log(validShuffle(str1, str2, shuffle) ? "YES" : "NO");

// This code is modified by Susobhan Akhuli

Output
YES


Time Complexity: O(n) //In the above-given approach, there is one loop for iterating over string which takes O(N) time in worst case. Therefore, the time complexity for this approach will be O(N).
Auxiliary Space: O(n) // an unordered map is used and in the worst case all elements will be stored inside it the hence algorithm takes up linear space



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads