Minimum Length of Anagram Concatenation
MediumUpdated: Aug 2, 2025
Practice on:
Problem
You are given a string s, which is known to be a concatenation of
anagrams of some string t.
Return the minimum possible length of the string t.
An anagram is formed by rearranging the letters of a string. For example, "aab", "aba", and, "baa" are anagrams of "aab".
Examples
Example 1
Input: s = "abba"
Output: 2
Explanation:
One possible string `t` could be `"ba"`.
Example 2
Input: s = "cdef"
Output: 4
Explanation:
One possible string `t` could be `"cdef"`, notice that `t` can be equal to
`s`.
Constraints
1 <= s.length <= 10^5sconsist only of lowercase English letters.
Solution
Method 1 – GCD of Character Counts
Intuition
Since s is a concatenation of anagrams of t, the frequency of each character in s must be a multiple of its frequency in t. The minimum possible length of t is the sum of the greatest common divisors (GCD) of the counts of each character in s.
Approach
- Count the frequency of each character in
s. - Compute the GCD of all character counts.
- The minimum length of
tis the sum of the counts of each character divided by the GCD.
Code
C++
class Solution {
public:
int minAnagramLength(string s) {
vector<int> cnt(26);
for (char c : s) cnt[c-'a']++;
int g = 0;
for (int x : cnt) if (x) g = gcd(g, x);
int ans = 0;
for (int x : cnt) if (x) ans += x / g;
return ans;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
};
Go
func minAnagramLength(s string) int {
cnt := make([]int, 26)
for _, c := range s {
cnt[c-'a']++
}
g := 0
gcd := func(a, b int) int {
for b != 0 {
a, b = b, a%b
}
return a
}
for _, x := range cnt {
if x > 0 {
if g == 0 { g = x } else { g = gcd(g, x) }
}
}
ans := 0
for _, x := range cnt {
if x > 0 {
ans += x / g
}
}
return ans
}
Java
class Solution {
public int minAnagramLength(String s) {
int[] cnt = new int[26];
for (char c : s.toCharArray()) cnt[c-'a']++;
int g = 0;
for (int x : cnt) if (x > 0) g = gcd(g, x);
int ans = 0;
for (int x : cnt) if (x > 0) ans += x / g;
return ans;
}
private int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
}
Kotlin
class Solution {
fun minAnagramLength(s: String): Int {
val cnt = IntArray(26)
for (c in s) cnt[c-'a']++
var g = 0
fun gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
for (x in cnt) if (x > 0) g = if (g == 0) x else gcd(g, x)
var ans = 0
for (x in cnt) if (x > 0) ans += x / g
return ans
}
}
Python
def min_anagram_length(s: str) -> int:
from math import gcd
from functools import reduce
from collections import Counter
cnt = Counter(s)
g = reduce(gcd, cnt.values())
return sum(x // g for x in cnt.values())
Rust
impl Solution {
pub fn min_anagram_length(s: String) -> i32 {
let mut cnt = [0; 26];
for c in s.chars() {
cnt[c as usize - 'a' as usize] += 1;
}
let mut g = 0;
for &x in &cnt {
if x > 0 {
g = if g == 0 { x } else { gcd(g, x) };
}
}
let mut ans = 0;
for &x in &cnt {
if x > 0 {
ans += x / g;
}
}
ans
}
}
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { a } else { gcd(b, a % b) }
}
TypeScript
class Solution {
minAnagramLength(s: string): number {
const cnt = Array(26).fill(0);
for (const c of s) cnt[c.charCodeAt(0) - 97]++;
let g = 0;
const gcd = (a: number, b: number): number => b === 0 ? a : gcd(b, a % b);
for (const x of cnt) if (x > 0) g = g === 0 ? x : gcd(g, x);
let ans = 0;
for (const x of cnt) if (x > 0) ans += x / g;
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n), where n is the length of s. Counting and GCD are linear. - 🧺 Space complexity:
O(1), for character counts.