Given two strings a and b, find whether a can be formed from b by deleting some characters from b and rearranging the remaining characters. Return true if possible, else return false.
Examples:
Input: a = "GeeksforGeeks", b = "rteksfoGrdsskGeggehes"
Output: true
Explanation: Delete the extra characters from b and rearrange the remaining characters. Since b contains every character required to form "GeeksforGeeks" with the required frequencies, a can be formed.Input: a = "Hello", b = "Geek"
Output: false
Explanation: Even after deleting any characters and rearranging the remaining ones, b does not contain enough required characters (such as two 'l's and one 'o') to form "Hello". Hence, a cannot be formed.
Table of Content
[Naive Approach] Subsequence Generation - O(2ⁿ × n log n) Time and O(n) Space
Generate all subsequences of string b using recursion. For each subsequence, sort it and compare with sorted string a to check if they are anagrams.
- Use recursion to explore take/skip for each character of b
- At base case, sort current subsequence and sort a
- Compare both sorted strings
- If equal, return true
- Return false if no subsequence matches
#include <iostream>
#include <algorithm>
using namespace std;
// Generate all subsequences of b
bool solve(string& a, string& b, string current, int index) {
// We have considered all characters
if (index == b.size()) {
string temp = current;
string target = a;
sort(temp.begin(), temp.end());
sort(target.begin(), target.end());
return temp == target;
}
// Take the current character
if (solve(a, b, current + b[index], index + 1)) {
return true;
}
// Skip the current character
if (solve(a, b, current, index + 1)) {
return true;
}
return false;
}
bool canFormAnagram(string& a, string& b) {
string current = "";
return solve(a, b, current, 0);
}
int main() {
string a = "abc";
string b = "bacde";
if (canFormAnagram(a, b)) {
cout << "true";
}
else {
cout << "false";
}
return 0;
}
import java.util.*;
class GfG {
// Generate all subsequences of b
static boolean solve(String a, String b, String current, int index) {
// We have considered all characters
if (index == b.length()) {
char[] tempArr = current.toCharArray();
char[] targetArr = a.toCharArray();
Arrays.sort(tempArr);
Arrays.sort(targetArr);
return Arrays.equals(tempArr, targetArr);
}
// Take the current character
if (solve(a, b, current + b.charAt(index), index + 1)) {
return true;
}
// Skip the current character
if (solve(a, b, current, index + 1)) {
return true;
}
return false;
}
static boolean canFormAnagram(String a, String b) {
String current = "";
return solve(a, b, current, 0);
}
public static void main(String[] args) {
String a = "abc";
String b = "bacde";
if (canFormAnagram(a, b)) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}
# Generate all subsequences of b
def solve(a, b, current, index):
# We have considered all characters
if index == len(b):
temp = sorted(current)
target = sorted(a)
return temp == target
# Take the current character
if solve(a, b, current + b[index], index + 1):
return True
# Skip the current character
if solve(a, b, current, index + 1):
return True
return False
def canFormAnagram(a, b):
current = ""
return solve(a, b, current, 0)
if __name__ == "__main__":
a = "abc"
b = "bacde"
if canFormAnagram(a, b):
print("true")
else:
print("false")
using System;
using System.Collections.Generic;
class GfG {
// Generate all subsequences of b
static bool solve(string a, string b, string current, int index) {
// We have considered all characters
if (index == b.Length) {
char[] tempArr = current.ToCharArray();
char[] targetArr = a.ToCharArray();
Array.Sort(tempArr);
Array.Sort(targetArr);
return new string(tempArr) == new string(targetArr);
}
// Take the current character
if (solve(a, b, current + b[index], index + 1)) {
return true;
}
// Skip the current character
if (solve(a, b, current, index + 1)) {
return true;
}
return false;
}
static bool canFormAnagram(string a, string b) {
string current = "";
return solve(a, b, current, 0);
}
static void Main(string[] args) {
string a = "abc";
string b = "bacde";
if (canFormAnagram(a, b)) {
Console.WriteLine("true");
} else {
Console.WriteLine("false");
}
}
}
// Generate all subsequences of b
function solve(a, b, current, index) {
// We have considered all characters
if (index === b.length) {
let temp = current.split('').sort().join('');
let target = a.split('').sort().join('');
return temp === target;
}
// Take the current character
if (solve(a, b, current + b[index], index + 1)) {
return true;
}
// Skip the current character
if (solve(a, b, current, index + 1)) {
return true;
}
return false;
}
function canFormAnagram(a, b) {
let current = "";
return solve(a, b, current, 0);
}
const a = "abc";
const b = "bacde";
if (canFormAnagram(a, b)) {
console.log("true");
} else {
console.log("false");
}
Output
true
[Expected Approach] Frequency Count - O(n + m) Time and O(n) Space
To check if a can be formed as an anagram using a subsequence of b, count frequency of characters in b and subtract frequency of characters in a. If any count becomes negative, b lacks required characters.
- Create frequency map for characters in b
- Decrement frequency for each character in a
- Check if any frequency is negative
- Return true if all frequencies are non-negative
#include <iostream>
#include <vector>
using namespace std;
bool canFormAnagram(string &a, string &b)
{
unordered_map<char, int> freq;
// increasing frequency for every character in b
for (int i = 0; i < b.length(); i++)
{
freq[b[i]]++;
}
// decreasing frequency for every character in a
for (int i = 0; i < a.length(); i++)
{
freq[a[i]]--;
}
// if any character's frequency goes negative,
// b doesn't have enough of that character
for (auto i : freq)
{
if (i.second < 0)
return false;
}
return true;
}
int main()
{
string a = "abc";
string b = "bacde";
if (canFormAnagram(a, b))
{
cout << "true";
}
else
{
cout << "false";
}
return 0;
}
import java.util.*;
class GfG {
static boolean canFormAnagram(String a, String b) {
Map<Character, Integer> freq = new HashMap<>();
// increasing frequency for every character in b
for (int i = 0; i < b.length(); i++) {
char c = b.charAt(i);
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
// decreasing frequency for every character in a
for (int i = 0; i < a.length(); i++) {
char c = a.charAt(i);
freq.put(c, freq.getOrDefault(c, 0) - 1);
}
// if any character's frequency goes negative,
// b doesn't have enough of that character
for (int count : freq.values()) {
if (count < 0)
return false;
}
return true;
}
public static void main(String[] args) {
String a = "abc";
String b = "bacde";
if (canFormAnagram(a, b)) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}
def canFormAnagram(a, b):
freq = {}
# increasing frequency for every character in b
for ch in b:
freq[ch] = freq.get(ch, 0) + 1
# decreasing frequency for every character in a
for ch in a:
freq[ch] = freq.get(ch, 0) - 1
# if any character's frequency goes negative,
# b doesn't have enough of that character
for count in freq.values():
if count < 0:
return False
return True
if __name__ == "__main__":
a = "abc"
b = "bacde"
if canFormAnagram(a, b):
print("true")
else:
print("false")
using System;
using System.Collections.Generic;
class GfG {
static bool canFormAnagram(string a, string b) {
Dictionary<char, int> freq = new Dictionary<char, int>();
// increasing frequency for every character in b
foreach (char c in b) {
if (freq.ContainsKey(c))
freq[c]++;
else
freq[c] = 1;
}
// decreasing frequency for every character in a
foreach (char c in a) {
if (freq.ContainsKey(c))
freq[c]--;
else
freq[c] = -1;
}
// if any character's frequency goes negative,
// b doesn't have enough of that character
foreach (int count in freq.Values) {
if (count < 0)
return false;
}
return true;
}
static void Main(string[] args) {
string a = "abc";
string b = "bacde";
if (canFormAnagram(a, b)) {
Console.WriteLine("true");
} else {
Console.WriteLine("false");
}
}
}
function canFormAnagram(a, b) {
let freq = new Map();
// increasing frequency for every character in b
for (let ch of b) {
freq.set(ch, (freq.get(ch) || 0) + 1);
}
// decreasing frequency for every character in a
for (let ch of a) {
freq.set(ch, (freq.get(ch) || 0) - 1);
}
// if any character's frequency goes negative,
// b doesn't have enough of that character
for (let count of freq.values()) {
if (count < 0)
return false;
}
return true;
}
const a = "abc";
const b = "bacde";
if (canFormAnagram(a, b)) {
console.log("true");
} else {
console.log("false");
}
Output
true