🧠
Brute Force (Compare Every Pair)
💡 This approach exists to establish a baseline understanding by directly comparing strings to find anagrams, even though it is inefficient. It helps beginners grasp the problem's nature before optimizing.
Intuition
Check every pair of strings to see if they are anagrams by comparing their sorted forms or character counts, then group them accordingly.
Algorithm
- Initialize an empty list to hold groups of anagrams.
- For each string in the input list, check if it is an anagram of any existing group by comparing with each group's representative string.
- If it matches, add it to that group; otherwise, create a new group with this string.
- Return the list of groups after processing all strings.
💡 This algorithm is straightforward but involves many repeated comparisons, making it slow for large inputs.
def groupAnagrams(strs):
groups = []
for s in strs:
found = False
for group in groups:
if sorted(s) == sorted(group[0]):
group.append(s)
found = True
break
if not found:
groups.append([s])
return groups
# Driver code
if __name__ == '__main__':
input_list = ["eat", "tea", "tan", "ate", "nat", "bat"]
print(groupAnagrams(input_list))
Line Notes
groups = []Initialize the list to store groups of anagrams
for s in strs:Iterate over each string to place it in a group
for group in groups:Check each existing group to find a matching anagram group
if sorted(s) == sorted(group[0]):Compare sorted characters to detect anagrams
group.append(s)Add string to the matching group
if not found:If no group matched, create a new group with this string
import java.util.*;
public class GroupAnagrams {
public static List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> groups = new ArrayList<>();
for (String s : strs) {
boolean found = false;
for (List<String> group : groups) {
if (isAnagram(s, group.get(0))) {
group.add(s);
found = true;
break;
}
}
if (!found) {
List<String> newGroup = new ArrayList<>();
newGroup.add(s);
groups.add(newGroup);
}
}
return groups;
}
private static boolean isAnagram(String s1, String s2) {
char[] a1 = s1.toCharArray();
char[] a2 = s2.toCharArray();
Arrays.sort(a1);
Arrays.sort(a2);
return Arrays.equals(a1, a2);
}
public static void main(String[] args) {
String[] input = {"eat", "tea", "tan", "ate", "nat", "bat"};
System.out.println(groupAnagrams(input));
}
}
Line Notes
List<List<String>> groups = new ArrayList<>();Initialize list to hold groups
for (String s : strs)Iterate over each string
for (List<String> group : groups)Check existing groups for anagram match
if (isAnagram(s, group.get(0)))Compare current string with group's first string
group.add(s);Add string to matched group
if (!found)Create new group if no match found
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool isAnagram(const string& s1, const string& s2) {
string a1 = s1, a2 = s2;
sort(a1.begin(), a1.end());
sort(a2.begin(), a2.end());
return a1 == a2;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> groups;
for (const string& s : strs) {
bool found = false;
for (auto& group : groups) {
if (isAnagram(s, group[0])) {
group.push_back(s);
found = true;
break;
}
}
if (!found) {
groups.push_back({s});
}
}
return groups;
}
int main() {
vector<string> input = {"eat", "tea", "tan", "ate", "nat", "bat"};
vector<vector<string>> result = groupAnagrams(input);
for (auto& group : result) {
for (auto& word : group) {
cout << word << " ";
}
cout << endl;
}
return 0;
}
Line Notes
vector<vector<string>> groups;Initialize groups container
for (const string& s : strs)Iterate over each string
for (auto& group : groups)Check each existing group for anagram match
if (isAnagram(s, group[0]))Compare current string with group's first string
group.push_back(s);Add string to matched group
if (!found)Create new group if no match found
function isAnagram(s1, s2) {
return s1.split('').sort().join('') === s2.split('').sort().join('');
}
function groupAnagrams(strs) {
const groups = [];
for (const s of strs) {
let found = false;
for (const group of groups) {
if (isAnagram(s, group[0])) {
group.push(s);
found = true;
break;
}
}
if (!found) {
groups.push([s]);
}
}
return groups;
}
// Test
const input = ["eat", "tea", "tan", "ate", "nat", "bat"];
console.log(groupAnagrams(input));
Line Notes
const groups = [];Initialize array to hold groups
for (const s of strs)Iterate over each string
for (const group of groups)Check existing groups for anagram match
if (isAnagram(s, group[0]))Compare current string with group's first string
group.push(s);Add string to matched group
if (!found)Create new group if no match found
TimeO(n^2 * k log k)
SpaceO(n * k)
For each of the n strings, we compare with up to n groups. Each comparison sorts strings of length k, costing k log k. Hence O(n^2 * k log k). Space stores all strings.
💡 If n=1000 and k=10, this means about 1,000,000 comparisons each sorting 10 characters, which is very slow.
Interview Verdict: TLE / Use only to introduce
This approach is too slow for large inputs but helps understand the problem before optimizing.