Given an array of words arr[], the task is to groups strings that are anagrams. An anagram is a word or phrase formed by rearranging the letters of another, using all the original letters exactly once.
Example:
Input: arr[] = ["act", "god", "cat", "dog", "tac"]
Output: [["act", "cat", "tac"], ["god", "dog"]]
Explanation: There are 2 groups of anagrams "god", "dog" make group 1. "act", "cat", "tac" make group 2.Input: arr[] = ["listen", "silent", "enlist", "abc", "cab", "bac", "rat", "tar", "art"]
Output: [["abc", "cab", "bac"], ["listen", "silent", "enlist"],["rat", "tar", "art"]]
Explanation:
Group 1: "abc", "bac" and "cab" are anagrams.
Group 2: "listen", "silent" and "enlist" are anagrams.
Group 3: "rat", "tar" and "art" are anagrams.
Using Sorted Words as Keys
The idea is that if we sort two strings which are anagrams of each other, then the sorted strings will always be the same. So, we can maintain a hash map or dictionary with the sorted strings as keys and the index of the anagram group in the result array as the value.
// C++ Code to group anagrams together by using sorted
// words as keys
#include <bits/stdc++.h>
using namespace std;
vector<vector<string>> anagrams(vector<string> &arr) {
vector<vector<string>> res;
unordered_map<string, int> mp;
for (int i = 0; i < arr.size(); i++) {
string s = arr[i];
// Find the key by sorting the string
sort(s.begin(), s.end());
// If key is not present in the hash map, add
// an empty group (vector) in the result and
// store the index of the group in hash map
if (mp.find(s) == mp.end()) {
mp[s] = res.size();
res.push_back({});
}
// Insert the string in its correct group
res[mp[s]].push_back(arr[i]);
}
return res;
}
int main() {
vector<string> arr = {"act", "god", "cat", "dog", "tac"};
vector<vector<string>> res = anagrams(arr);
for(int i = 0; i < res.size(); i++) {
for(int j = 0; j < res[i].size(); j++)
cout << res[i][j] << " ";
cout << "\n";
}
return 0;
}
// Java Code to group anagrams together by using sorted
// words as keys
import java.util.*;
class GfG {
static ArrayList<ArrayList<String>> anagrams(String[] arr) {
ArrayList<ArrayList<String>> res = new ArrayList<>();
HashMap<String, Integer> mp = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
String s = arr[i];
// Find the key by sorting the string
char[] chars = s.toCharArray();
Arrays.sort(chars);
s = new String(chars);
// If key is not present in the hash map, add
// an empty group (ArrayList) in the result and
// store the index of the group in hash map
if (!mp.containsKey(s)) {
mp.put(s, res.size());
res.add(new ArrayList<>());
}
// Insert the string in its correct group
res.get(mp.get(s)).add(arr[i]);
}
return res;
}
public static void main(String[] args) {
String[] arr = {"act", "god", "cat", "dog", "tac"};
ArrayList<ArrayList<String>> res = anagrams(arr);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res.get(i).size(); j++)
System.out.print(res.get(i).get(j) + " ");
System.out.println();
}
}
}
# Python Code to group anagrams together by using sorted
# words as keys
from collections import defaultdict
def anagrams(arr):
res = []
mp = {}
for i in range(len(arr)):
s = arr[i]
# Find the key by sorting the string
s = ''.join(sorted(s))
# If key is not present in the hash map, add
# an empty group (list) in the result and
# store the index of the group in hash map
if s not in mp:
mp[s] = len(res)
res.append([])
# Insert the string in its correct group
res[mp[s]].append(arr[i])
return res
# Driver code
if __name__ == "__main__":
arr = ["act", "god", "cat", "dog", "tac"]
res = anagrams(arr)
for group in res:
print(" ".join(group))
// C# Code to group anagrams together by using sorted
// words as keys
using System;
using System.Collections.Generic;
class GfG {
static List<List<string>> Anagrams(string[] arr) {
List<List<string>> res = new List<List<string>>();
Dictionary<string, int> mp = new Dictionary<string, int>();
for (int i = 0; i < arr.Length; i++) {
string s = arr[i];
// Find the key by sorting the string
char[] charArray = s.ToCharArray();
Array.Sort(charArray);
s = new string(charArray);
// If key is not present in the hash map, add
// an empty group (list) in the result and
// store the index of the group in hash map
if (!mp.ContainsKey(s)) {
mp[s] = res.Count;
res.Add(new List<string>());
}
// Insert the string in its correct group
res[mp[s]].Add(arr[i]);
}
return res;
}
static void Main(string[] args) {
string[] arr = new string[] { "act", "god", "cat", "dog", "tac" };
List<List<string>> res = Anagrams(arr);
for (int i = 0; i < res.Count; i++)
{
for (int j = 0; j < res[i].Count; j++)
Console.Write(res[i][j] + " ");
Console.WriteLine();
}
}
}
// JavaScript Code to group anagrams together by using sorted
// words as keys
function anagrams(arr) {
let res = [];
let mp = new Map();
for (let i = 0; i < arr.length; i++) {
let s = arr[i];
// Find the key by sorting the string
s = s.split('').sort().join('');
// If key is not present in the hash map, add
// an empty group (array) in the result and
// store the index of the group in hash map
if (!mp.has(s)) {
mp.set(s, res.length);
res.push([]);
}
// Insert the string in its correct group
res[mp.get(s)].push(arr[i]);
}
return res;
}
// Driver Code
let arr = ["act", "god", "cat", "dog", "tac"];
let res = anagrams(arr);
for (let i = 0; i < res.length; i++) {
console.log(res[i].join(" "));
}
Output
act cat tac god dog
Time Complexity: O(n * k * log(k)), where n is the number of words and k is the maximum length of a word.
Auxiliary Space: O(n * k), to store the result.
Related Article: Group Anagrams Together