Problem

Given a string s, return true ifs _is agood string, or _false otherwise.

A string s is good if all the characters that appear in s have the same number of occurrences (i.e., the same frequency).

Examples

Example 1

1
2
3
Input: s = "abacbc"
Output: true
Explanation: The characters that appear in s are 'a', 'b', and 'c'. All characters occur 2 times in s.

Example 2

1
2
3
4
Input: s = "aaabb"
Output: false
Explanation: The characters that appear in s are 'a' and 'b'.
'a' occurs 3 times while 'b' occurs 2 times, which is not the same number of times.

Constraints

  • 1 <= s.length <= 1000
  • s consists of lowercase English letters.

Solution

Method 1 – Hash Map Frequency Check

Intuition

The key idea is that if all characters in the string appear the same number of times, then the set of their frequencies will have only one unique value. For example, in “abacbc”, ‘a’, ‘b’, and ‘c’ all appear 2 times, so the set of frequencies is {2}.

Approach

  1. Create a hash map (or array) to count the frequency of each character in the string.
  2. Collect all the frequency values.
  3. Check if all frequencies are the same by converting them to a set and checking its length.
  4. Return true if all frequencies are equal, otherwise false.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution {
public:
    bool areOccurrencesEqual(string s) {
        int freq[26] = {0};
        for (char c : s) freq[c - 'a']++;
        int ans = 0;
        for (int i = 0; i < 26; ++i) {
            if (freq[i] == 0) continue;
            if (ans == 0) ans = freq[i];
            else if (freq[i] != ans) return false;
        }
        return true;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func areOccurrencesEqual(s string) bool {
    freq := make(map[rune]int)
    for _, c := range s {
        freq[c]++
    }
    ans := 0
    for _, v := range freq {
        if ans == 0 {
            ans = v
        } else if v != ans {
            return false
        }
    }
    return true
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    public boolean areOccurrencesEqual(String s) {
        int[] freq = new int[26];
        for (char c : s.toCharArray()) freq[c - 'a']++;
        int ans = 0;
        for (int f : freq) {
            if (f == 0) continue;
            if (ans == 0) ans = f;
            else if (f != ans) return false;
        }
        return true;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    fun areOccurrencesEqual(s: String): Boolean {
        val freq = IntArray(26)
        for (c in s) freq[c - 'a']++
        var ans = 0
        for (f in freq) {
            if (f == 0) continue
            if (ans == 0) ans = f
            else if (f != ans) return false
        }
        return true
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def areOccurrencesEqual(s: str) -> bool:
    freq: dict[str, int] = {}
    for c in s:
        freq[c] = freq.get(c, 0) + 1
    ans = 0
    for v in freq.values():
        if ans == 0:
            ans = v
        elif v != ans:
            return False
    return True
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
impl Solution {
    pub fn are_occurrences_equal(s: String) -> bool {
        let mut freq = [0; 26];
        for b in s.bytes() {
            freq[(b - b'a') as usize] += 1;
        }
        let mut ans = 0;
        for &f in freq.iter() {
            if f == 0 { continue; }
            if ans == 0 { ans = f; }
            else if f != ans { return false; }
        }
        true
    }
}

Complexity

  • ⏰ Time complexity: O(n), where n is the length of the string.
  • 🧺 Space complexity: O(1), since the alphabet size is constant.