Compare every pair of strings and swap adjacent strings when they are anagrams, pushing matched anagrams together. This is effectively a bubble-style clustering that requires no extra data structures beyond an anagram test.
#include<string>#include<vector>using std::string;
using std::vector;
classSolution {
public:staticbool areAnagrams(const string &a, const string &b) {
if (a.size() != b.size()) return false;
int cnt[26] = {0};
for (char c : a) ++cnt[c -'a'];
for (char c : b) --cnt[c -'a'];
for (int v : cnt) if (v !=0) return false;
return true;
}
voidsortAnagrams(vector<string>& arr) {
int n = arr.size();
for (int i =0; i < n -1; ++i) {
for (int j = i +1; j < n; ++j) {
if (areAnagrams(arr[i], arr[j])) {
std::swap(arr[i +1], arr[j]);
}
}
}
}
};
import java.util.*;
publicclassSolution {
privatestaticbooleanareAnagrams(String a, String b) {
if (a.length() != b.length()) returnfalse;
int[] cnt =newint[26];
for (int i = 0; i < a.length(); ++i) cnt[a.charAt(i)-'a']++;
for (int i = 0; i < b.length(); ++i) cnt[b.charAt(i)-'a']--;
for (int v : cnt) if (v != 0) returnfalse;
returntrue;
}
publicvoidsortAnagrams(String[] arr) {
int n = arr.length;
for (int i = 0; i < n-1; ++i) {
for (int j = i+1; j < n; ++j) {
if (areAnagrams(arr[i], arr[j])) {
String tmp = arr[i+1]; arr[i+1]= arr[j]; arr[j]= tmp;
}
}
}
}
}
classSolution {
privatefunareAnagrams(a: String, b: String): Boolean {
if (a.length != b.length) returnfalseval cnt = IntArray(26)
for (i in a.indices) cnt[a[i]-'a']++for (i in b.indices) cnt[b[i]-'a']--for (v in cnt) if (v !=0) returnfalsereturntrue }
funsortAnagrams(arr: Array<String>) {
val n = arr.size
for (i in0 until n-1) {
for (j in i+1 until n) {
if (areAnagrams(arr[i], arr[j])) {
val tmp = arr[i+1]; arr[i+1] = arr[j]; arr[j] = tmp
}
}
}
}
}
from typing import List
classSolution:
@staticmethoddefare_anagrams(a: str, b: str) -> bool:
if len(a) != len(b):
returnFalse cnt = [0]*26for ch in a:
cnt[ord(ch)-ord('a')] +=1for ch in b:
cnt[ord(ch)-ord('a')] -=1return all(v ==0for v in cnt)
defsortAnagrams(self, arr: List[str]) ->None:
n = len(arr)
for i in range(n-1):
for j in range(i+1, n):
if Solution.are_anagrams(arr[i], arr[j]):
arr[i+1], arr[j] = arr[j], arr[i+1]
Anagrams share the same multiset of characters. Use a canonical representation (sorted characters) as a key and collect original strings into buckets per key. Rewriting the array from these buckets places anagrams next to each other.
import java.util.*;
publicclassSolution {
publicvoidsortAnagrams(String[] arr) {
Map<String, List<String>> buckets =new LinkedHashMap<>();
for (String s : arr) {
char[] a = s.toCharArray();
Arrays.sort(a);
String key =new String(a);
buckets.computeIfAbsent(key, k ->new ArrayList<>()).add(s);
}
int idx = 0;
for (List<String> group : buckets.values()) {
for (String v : group) {
arr[idx++]= v;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funsortAnagrams(arr: Array<String>) {
val buckets = linkedMapOf<String, MutableList<String>>()
for (s in arr) {
val key = s.toCharArray().sorted().joinToString(separator = "")
buckets.computeIfAbsent(key) { mutableListOf() }.add(s)
}
var idx = 0for (group in buckets.values) {
for (v in group) {
arr[idx++] = v
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from typing import List
from collections import OrderedDict
classSolution:
defsortAnagrams(self, arr: List[str]) ->None:
buckets: "OrderedDict[str, List[str]]"= OrderedDict()
for s in arr:
key =''.join(sorted(s))
if key notin buckets:
buckets[key] = []
buckets[key].append(s)
idx =0for group in buckets.values():
for v in group:
arr[idx] = v
idx +=1
Precompute an anagram key for each string (sorted characters), attach it to the original string, and sort the array by the key. This clusters all strings with identical keys together; using a stable sort preserves relative order within each group.
⏰ Time complexity:O(N * K log K + N log N * K) – sorting characters inside each string costs O(K log K) per string; the sort of N keys costs O(N log N) comparisons and each comparison of keys takes up to O(K).
🧺 Space complexity:O(N * K) – storing the key for each string (pair array) requires extra space proportional to total input.
import java.util.*;
publicclassSolution {
publicvoidsortAnagrams(String[] arr) {
int n = arr.length;
String[][] pairs =new String[n][2];
for (int i = 0; i < n; ++i) {
char[] a = arr[i].toCharArray();
Arrays.sort(a);
pairs[i][0]=new String(a);
pairs[i][1]= arr[i];
}
Arrays.sort(pairs, new Comparator<String[]>() {
publicintcompare(String[] a, String[] b) {
return a[0].compareTo(b[0]);
}
});
for (int i = 0; i < n; ++i)
arr[i]= pairs[i][1];
}
}
1
2
3
4
5
6
7
classSolution {
funsortAnagrams(arr: Array<String>) {
val pairs = arr.map { s -> Pair(s.toCharArray().sorted().joinToString(""), s) }.toMutableList()
pairs.sortBy { it.first }
for (i in pairs.indices) arr[i] = pairs[i].second
}
}
1
2
3
4
5
6
7
8
from typing import List
classSolution:
defsortAnagrams(self, arr: List[str]) ->None:
pairs = [ (''.join(sorted(s)), s) for s in arr ]
pairs.sort()
for i, (_, v) in enumerate(pairs):
arr[i] = v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pubstructSolution;
impl Solution {
pubfnsort_anagrams(arr: &mut [String]) {
letmut pairs: Vec<(String, String)>= Vec::with_capacity(arr.len());
for s in arr.iter() {
letmut chars: Vec<char>= s.chars().collect();
chars.sort();
let key: String = chars.into_iter().collect();
pairs.push((key, s.clone()));
}
pairs.sort_by(|a, b| a.0.cmp(&b.0));
for i in0..pairs.len() {
arr[i] = pairs[i].1.clone();
}
}
}