Number of Wonderful Substrings

Count substrings where at most one letter has an odd count — prefix bitmask + hash map.

Medium
Time O(N) Space O(2^10)
LeetCode
3 min read
hash-map bitmask prefix-sum

Problem#

A “wonderful” string has at most one letter appearing an odd number of times. Given a string word of letters 'a'..'j', count the number of non-empty substrings that are wonderful.

Examples#

  • word = "aba"4 ("a", "b", "a", "aba").
  • word = "aabb"9.

Constraints#

  • 1 <= word.length <= 10^5, characters from 'a' to 'j'.

Hints#

Hint 1
Use a 10-bit mask tracking parity of each letter’s count in the prefix.
Hint 2
A substring is wonderful iff its mask differs from a previous prefix mask in 0 or 1 bits.

Approach#

Prefix bitmask m toggles bit c - 'a' on each character. For each new m, count: (a) prior occurrences of the same m (zero odd letters) and (b) prior occurrences of m ^ (1 << k) for each k (exactly one odd letter). Store mask occurrences in a fixed int[1024]. Initialize freq[0] = 1 to count substrings starting at index 0.

Solution#

Number of Wonderful Substrings
class Solution {
public:
long long wonderfulSubstrings(string word) {
long long ans = 0;
int freq[1024] = {0};
freq[0] = 1;
int mask = 0;
for (char c : word) {
mask ^= 1 << (c - 'a');
ans += freq[mask];
for (int k = 0; k < 10; ++k) ans += freq[mask ^ (1 << k)];
++freq[mask];
}
return ans;
}
};

Editorial#

Parity-bitmask is the canonical trick for “at most k odd counts.” The mask of any substring word[i..j] is prefix[j+1] XOR prefix[i]; wonderful means this XOR is 0 (no odd letters) or a power of two (exactly one odd). We sweep prefixes left to right, accumulating answers from the 11 relevant prior masks at each step.

Complexity#

  • Time: O(N * 10).
  • Space: O(2^10) = O(1).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.