Given two strings of lowercase alphabets and a value k, the task is to find if two strings are K-anagrams of each other or not.
Two strings are called k-anagrams if following two conditions are true.
- Both have same number of characters.
- Two strings can become anagram by changing at most k characters in a string.
Examples :
Input: str1 = "anagram" , str2 = "grammar" , k = 3
Output: Yes
Explanation: We can update maximum 3 values and
it can be done in changing only 'r' to 'n'
and 'm' to 'a' in str2.
Input: str1 = "geeks", str2 = "eggkf", k = 1
Output: No
Explanation: We can update or modify only 1
value but there is a need of modifying 2 characters.
i.e. g and f in str 2.
BRUTE METHOD:(USING MAP)
Intuition:
- We create a Map<Character,Integer> to store the frequency-map of the string.
- We push all the character of string 1 in the map.
- Then we iterate through the string 2 and if the character if present ,we decrease it value by 1.
- At-last, we iterate over the map and store the frequency of the remaining characters in a variable count and check if its greater than K, we return false else return true.
Implementation:
C++
#include <iostream>
#include <unordered_map>
using namespace std;
bool areKAnagrams(string s1, string s2, int k)
{
if (s1.length() != s2.length()) {
return false ;
}
unordered_map< char , int > map;
for ( int i = 0; i < s1.length(); i++) {
char ch = s1[i];
map[ch]++;
}
for ( int i = 0; i < s2.length(); i++) {
char ch = s2[i];
if (map[ch] > 0) {
map[ch]--;
}
}
int count = 0;
for ( auto it = map.begin(); it != map.end(); it++) {
count += it->second;
}
if (count > k)
return false ;
else
return true ;
}
int main()
{
string str1 = "anagram" ;
string str2 = "grammar" ;
int k = 2;
if (areKAnagrams(str1, str2, k))
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static boolean areKAnagrams(String s1, String s2, int k)
{
if (s1.length() != s2.length()) {
return false ;
}
Map<Character, Integer> map = new HashMap<>();
for ( int i = 0 ; i < s1.length(); i++) {
char ch = s1.charAt(i);
map.put(ch, map.getOrDefault(ch, 0 ) + 1 );
}
for ( int i = 0 ; i < s2.length(); i++) {
char ch = s2.charAt(i);
if (map.getOrDefault(ch, 0 ) > 0 ) {
map.put(ch, map.get(ch) - 1 );
}
}
int count = 0 ;
for ( char ch : map.keySet()) {
count += map.get(ch);
}
if (count > k)
return false ;
else
return true ;
}
public static void main(String[] args)
{
String str1 = "anagram" ;
String str2 = "grammar" ;
int k = 2 ;
if (areKAnagrams(str1, str2, k))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
from collections import defaultdict
def are_k_anagrams(s1, s2, k):
if len (s1) ! = len (s2):
return False
count = defaultdict( int )
for ch in s1:
count[ch] + = 1
for ch in s2:
if count[ch] > 0 :
count[ch] - = 1
diff_count = sum (count.values())
if diff_count > k:
return False
else :
return True
str1 = "anagram"
str2 = "grammar"
k = 2
if are_k_anagrams(str1, str2, k):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool AreKAnagrams( string s1, string s2, int k)
{
if (s1.Length != s2.Length)
{
return false ;
}
Dictionary< char , int > map = new Dictionary< char , int >();
foreach ( char ch in s1)
{
if (map.ContainsKey(ch))
{
map[ch]++;
}
else
{
map[ch] = 1;
}
}
foreach ( char ch in s2)
{
if (map.ContainsKey(ch) && map[ch] > 0)
{
map[ch]--;
}
}
int count = 0;
foreach ( var pair in map)
{
count += pair.Value;
}
return count <= k;
}
static void Main()
{
string str1 = "anagram" ;
string str2 = "grammar" ;
int k = 2;
if (AreKAnagrams(str1, str2, k))
{
Console.WriteLine( "Yes" );
}
else
{
Console.WriteLine( "No" );
}
}
}
|
Javascript
function areKAnagrams(s1, s2, k) {
if (s1.length !== s2.length) {
return false ;
}
const map = new Map();
for (let i = 0; i < s1.length; i++) {
const ch = s1[i];
if (map.has(ch)) {
map.set(ch, map.get(ch) + 1);
} else {
map.set(ch, 1);
}
}
for (let i = 0; i < s2.length; i++) {
const ch = s2[i];
if (map.has(ch) && map.get(ch) > 0) {
map.set(ch, map.get(ch) - 1);
}
}
let count = 0;
for (const [ch, freq] of map.entries()) {
count += freq;
}
return count <= k;
}
const str1 = "anagram" ;
const str2 = "grammar" ;
const k = 2;
if (areKAnagrams(str1, str2, k)) {
console.log( "Yes" );
} else {
console.log( "No" );
}
|
- Time Complexity: O(N)
- Auxiliary Space: O(N), since we are using a frequency map.
Method 1:
Below is a solution to check if two strings are k-anagrams of each other or not.
- Stores occurrence of all characters of both strings in separate count arrays.
- Count number of different characters in both strings (in this if a string has 4 a and second has 3 ‘a’ then it will be also counted.
- If count of different characters is less than or equal to k, then return true else false.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
bool arekAnagrams(string str1, string str2, int k)
{
int n = str1.length();
if (str2.length() != n)
return false ;
int count1[MAX_CHAR] = {0};
int count2[MAX_CHAR] = {0};
for ( int i = 0; i < n; i++)
count1[str1[i]- 'a' ]++;
for ( int i = 0; i < n; i++)
count2[str2[i]- 'a' ]++;
int count = 0;
for ( int i = 0; i < MAX_CHAR; i++)
if (count1[i] > count2[i])
count = count + abs (count1[i]-count2[i]);
return (count <= k);
}
int main()
{
string str1 = "anagram" ;
string str2 = "grammar" ;
int k = 2;
if (arekAnagrams(str1, str2, k))
cout << "Yes" ;
else
cout<< "No" ;
return 0;
}
|
C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int MAX_CHAR = 26;
bool arekAnagrams( char str1[], char str2[], int k)
{
int n = strlen (str1);
if ( strlen (str2) != n)
return false ;
int count1[MAX_CHAR];
int count2[MAX_CHAR];
for ( int i = 0; i < MAX_CHAR; i++) {
count1[i] = 0;
count2[i] = 0;
}
for ( int i = 0; i < n; i++)
count1[str1[i] - 'a' ]++;
for ( int i = 0; i < n; i++)
count2[str2[i] - 'a' ]++;
int count = 0;
for ( int i = 0; i < MAX_CHAR; i++)
if (count1[i] > count2[i])
count = count + abs (count1[i] - count2[i]);
return (count <= k);
}
int main()
{
char str1[] = "anagram" ;
char str2[] = "grammar" ;
int k = 2;
if (arekAnagrams(str1, str2, k))
printf ( "Yes\n" );
else
printf ( "No\n" );
return 0;
}
|
Java
public class GFG {
static final int MAX_CHAR = 26 ;
static boolean arekAnagrams(String str1, String str2,
int k)
{
int n = str1.length();
if (str2.length() != n)
return false ;
int [] count1 = new int [MAX_CHAR];
int [] count2 = new int [MAX_CHAR];
int count = 0 ;
for ( int i = 0 ; i < n; i++)
count1[str1.charAt(i) - 'a' ]++;
for ( int i = 0 ; i < n; i++)
count2[str2.charAt(i) - 'a' ]++;
for ( int i = 0 ; i < MAX_CHAR; i++)
if (count1[i] > count2[i])
count = count + Math.abs(count1[i] -
count2[i]);
return (count <= k);
}
public static void main(String args[])
{
String str1 = "anagram" ;
String str2 = "grammar" ;
int k = 2 ;
if (arekAnagrams(str1, str2, k))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
MAX_CHAR = 26
def arekAnagrams(str1, str2, k) :
n = len (str1)
if ( len (str2)! = n) :
return False
count1 = [ 0 ] * MAX_CHAR
count2 = [ 0 ] * MAX_CHAR
for i in range (n):
count1[ ord (str1[i]) -
ord ( 'a' )] + = 1
for i in range (n):
count2[ ord (str2[i]) -
ord ( 'a' )] + = 1
count = 0
for i in range (MAX_CHAR):
if (count1[i] > count2[i]) :
count = count + abs (count1[i] -
count2[i])
return (count < = k)
if __name__ = = '__main__' :
str1 = "anagram"
str2 = "grammar"
k = 2
if (arekAnagrams(str1, str2, k)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG {
static int MAX_CHAR = 26;
static bool arekAnagrams( string str1,
string str2,
int k)
{
int n = str1.Length;
if (str2.Length != n)
return false ;
int [] count1 = new int [MAX_CHAR];
int [] count2 = new int [MAX_CHAR];
int count = 0;
for ( int i = 0; i < n; i++)
count1[str1[i] - 'a' ]++;
for ( int i = 0; i < n; i++)
count2[str2[i] - 'a' ]++;
for ( int i = 0; i < MAX_CHAR; i++)
if (count1[i] > count2[i])
count = count + Math.Abs(count1[i] -
count2[i]);
return (count <= k);
}
public static void Main()
{
string str1 = "anagram" ;
string str2 = "grammar" ;
int k = 2;
if (arekAnagrams(str1, str2, k))
Console.Write( "Yes" );
else
Console.Write( "No" );
}
}
|
Javascript
<script>
let MAX_CHAR = 26;
function arekAnagrams(str1, str2, k)
{
let n = str1.length;
if (str2.length != n)
return false ;
let count1 = new Array(MAX_CHAR);
let count2 = new Array(MAX_CHAR);
let count = 0;
for (let i = 0; i < n; i++)
count1[str1[i].charCodeAt(0) -
'a' .charCodeAt(0)]++;
for (let i = 0; i < n; i++)
count2[str2[i].charCodeAt(0) -
'a' .charCodeAt(0)]++;
for (let i = 0; i < MAX_CHAR; i++)
if (count1[i] > count2[i])
count = count + Math.abs(count1[i] -
count2[i]);
return (count <= k);
}
let str1 = "anagram" ;
let str2 = "grammar" ;
let k = 2;
if (arekAnagrams(str1, str2, k))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
PHP
<?php
$MAX_CHAR = 26;
function arekAnagrams( $str1 , $str2 , $k )
{
global $MAX_CHAR ;
$n = strlen ( $str1 );
if ( strlen ( $str2 ) != $n )
return false;
$count1 = (0);
$count2 = (0);
$count = 0;
for ( $i = 0; $i < $MAX_CHAR ; $i ++)
if ( $count1 [ $i ] > $count2 [ $i ])
$count = $count + abs ( $count1 [ $i ] -
$count2 [ $i ]);
return ( $count <= $k );
}
$str1 = "anagram" ;
$str2 = "grammar" ;
$k = 2;
if (arekAnagrams( $str1 , $str2 , $k ))
echo "Yes" ;
else
echo "No" ;
?>
|
Time complexity: O(n)
Auxiliary Space: O(1)
Method 2: We can optimize above solution. Here we use only one count array to store counts of characters in str1. We traverse str2 and decrement occurrence of every character in count array that is present in str2. If we find a character that is not there in str1, we increment count of different characters. If count of different character become more than k, we return false.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
bool areKAnagrams(string str1, string str2, int k)
{
int n = str1.length();
if (str2.length() != n)
return false ;
int hash_str1[MAX_CHAR] = {0};
for ( int i = 0; i < n ; i++)
hash_str1[str1[i]- 'a' ]++;
int count = 0;
for ( int i = 0; i < n ; i++)
{
if (hash_str1[str2[i]- 'a' ] > 0)
hash_str1[str2[i]- 'a' ]--;
else
count++;
if (count > k)
return false ;
}
return true ;
}
int main()
{
string str1 = "fodr" ;
string str2 = "gork" ;
int k = 2;
if (areKAnagrams(str1, str2, k) == true )
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
C
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define MAX_CHAR 26
bool areKAnagrams( char * str1, char * str2, int k)
{
int n = strlen (str1);
if ( strlen (str2) != n)
return false ;
int hash_str1[MAX_CHAR] = { 0 };
for ( int i = 0; i < n; i++)
hash_str1[str1[i] - 'a' ]++;
int count = 0;
for ( int i = 0; i < n; i++) {
if (hash_str1[str2[i] - 'a' ] > 0)
hash_str1[str2[i] - 'a' ]--;
else
count++;
if (count > k)
return false ;
}
return true ;
}
int main()
{
char str1[] = "fodr" ;
char str2[] = "gork" ;
int k = 2;
if (areKAnagrams(str1, str2, k))
printf ( "Yes\n" );
else
printf ( "No\n" );
return 0;
}
|
Java
public class GFG {
static final int MAX_CHAR = 26 ;
static boolean areKAnagrams(String str1, String str2,
int k)
{
int n = str1.length();
if (str2.length() != n)
return false ;
int [] hash_str1 = new int [MAX_CHAR];
for ( int i = 0 ; i < n ; i++)
hash_str1[str1.charAt(i)- 'a' ]++;
int count = 0 ;
for ( int i = 0 ; i < n ; i++)
{
if (hash_str1[str2.charAt(i)- 'a' ] > 0 )
hash_str1[str2.charAt(i)- 'a' ]--;
else
count++;
if (count > k)
return false ;
}
return true ;
}
public static void main(String args[])
{
String str1 = "fodr" ;
String str2 = "gork" ;
int k = 2 ;
if (areKAnagrams(str1, str2, k) == true )
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
MAX_CHAR = 26 ;
def areKAnagrams(str1, str2, k):
n = len (str1);
if ( len (str2) ! = n):
return False ;
hash_str1 = [ 0 ] * (MAX_CHAR);
for i in range (n):
hash_str1[ ord (str1[i]) - ord ( 'a' )] + = 1 ;
count = 0 ;
for i in range (n):
if (hash_str1[ ord (str2[i]) - ord ( 'a' )] > 0 ):
hash_str1[ ord (str2[i]) - ord ( 'a' )] - = 1 ;
else :
count + = 1 ;
if (count > k):
return False ;
return True ;
str1 = "fodr" ;
str2 = "gork" ;
k = 2 ;
if (areKAnagrams(str1, str2, k) = = True ):
print ( "Yes" );
else :
print ( "No" );
|
C#
using System;
class GFG {
static int MAX_CHAR = 26;
static bool areKAnagrams(String str1, String str2,
int k)
{
int n = str1.Length;
if (str2.Length != n)
return false ;
int [] hash_str1 = new int [MAX_CHAR];
for ( int i = 0; i < n ; i++)
hash_str1[str1[i]- 'a' ]++;
int count = 0;
for ( int i = 0; i < n ; i++)
{
if (hash_str1[str2[i]- 'a' ] > 0)
hash_str1[str2[i]- 'a' ]--;
else
count++;
if (count > k)
return false ;
}
return true ;
}
static void Main()
{
String str1 = "fodr" ;
String str2 = "gork" ;
int k = 2;
if (areKAnagrams(str1, str2, k) == true )
Console.Write( "Yes" );
else
Console.Write( "No" );
}
}
|
Javascript
<script>
let MAX_CHAR = 26;
function areKAnagrams(str1, str2, k)
{
let n = str1.length;
if (str2.length != n)
return false ;
let hash_str1 = Array(MAX_CHAR);
hash_str1.fill(0);
for (let i = 0; i < n ; i++)
hash_str1[str1[i].charCodeAt()-
'a' .charCodeAt()]++;
let count = 0;
for (let i = 0; i < n ; i++)
{
if (hash_str1[str2[i].charCodeAt()-
'a' .charCodeAt()] > 0)
hash_str1[str2[i].charCodeAt()-
'a' .charCodeAt()]--;
else
count++;
if (count > k)
return false ;
}
return true ;
}
let str1 = "fodr" ;
let str2 = "gork" ;
let k = 2;
if (areKAnagrams(str1, str2, k) == true )
document.write( "Yes" );
else
document.write( "No" );
</script>
|
PHP
<?php
$MAX_CHAR = 26;
function areKAnagrams( $str1 ,
$str2 , $k )
{
global $MAX_CHAR ;
$n = strlen ( $str1 );
if ( strlen ( $str2 ) != $n )
return false;
$hash_str1 = array (0);
for ( $i = 0; $i < $n ; $i ++)
$hash_str1 [ $str1 [ $i ] - 'a' ]++;
$count = 0;
for ( $i = 0; $i < $n ; $i ++)
{
if ( $hash_str1 [ $str2 [ $i ] - 'a' ] > 0)
$hash_str1 [ $str2 [ $i ] - 'a' ]--;
else
$count ++;
if ( $count > $k )
return false;
}
return true;
}
$str1 = "fodr" ;
$str2 = "gork" ;
$k = 2;
if (areKAnagrams( $str1 , $str2 , $k ) == true)
echo "Yes" ;
else
echo "No" ;
?>
|
Time complexity: O(n)
Auxiliary Space: O(1)
This article is contributed by Sahil Chhabra (akku). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.