Number of Wonderful Substrings - Complete Solution Guide
Number of Wonderful Substrings is LeetCode problem 1915, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
A wonderful string is a string where at most one letter appears an odd number of times. For example, "ccjjc" and "abab" are wonderful, but "ab" is not. Given a string word that consists of the first ten lowercase English letters ( 'a' through 'j' ), return the number of wonderful non-empty substrings in word . If the same substring appears multiple times in word , then count each occurrence separately. A substring is a contiguous sequence of characters in a string. Example 1: Input: word = "aba"
Detailed Explanation
The problem asks us to find the number of 'wonderful' substrings within a given string `word`. A 'wonderful' string is defined as a string where at most one character appears an odd number of times. The input string `word` consists only of lowercase English letters from 'a' to 'j'. We need to count all non-empty substrings of `word` and determine how many of them are 'wonderful'. Each occurrence of the same substring should be counted separately.
Solution Approach
The solution utilizes bit manipulation and a frequency count to efficiently determine the number of wonderful substrings. It iterates through the string, maintaining a bitmask representing the parity of each character encountered so far. The bitmask is updated using XOR (^) operations. For each character, the solution checks how many previous substrings have the same bitmask (meaning the substring between those indices has all characters appearing an even number of times) and how many substrings have a bitmask that differs by only one bit (meaning exactly one character appears an odd number of times). A `counts` array stores the number of times each bitmask has been seen so far.
Step-by-Step Algorithm
- Step 1: Initialize a `counts` array of size 1024 (2^10) to store the frequency of each bitmask. Initialize `counts[0]` to 1 because an empty substring has a mask of 0 (all characters have even counts).
- Step 2: Initialize a `result` variable to 0. This variable will store the total number of wonderful substrings.
- Step 3: Initialize a `mask` variable to 0. This variable will store the bitmask representing the parity of characters encountered so far.
- Step 4: Iterate through the input string `word` character by character.
- Step 5: For each character, calculate its index by subtracting the ASCII value of 'a' from its ASCII value (e.g., 'b' - 'a' = 1).
- Step 6: Update the `mask` by XORing it with `(1 << char_index)`. This toggles the bit corresponding to the character's index, effectively tracking the parity of the character.
- Step 7: Increment the `result` by `counts[mask]`. This adds the number of substrings ending at the current index with all even character counts to the total.
- Step 8: Iterate through the possible single-character odd counts (from 0 to 9). For each character index `i`, increment the `result` by `counts[mask ^ (1 << i)]`. This adds the number of substrings ending at the current index with only one odd character count to the total.
- Step 9: Increment `counts[mask]` by 1 to update the frequency count of the current bitmask.
- Step 10: After iterating through all characters, return the `result`.
Key Insights
- Insight 1: Use bit manipulation to efficiently track the parity (even or odd count) of each character ('a' to 'j'). A mask can represent the parity of all characters, where the i-th bit represents the parity of the i-th character.
- Insight 2: The prefix sum concept can be adapted to this problem. Instead of storing the sum, we store the parity mask. The number of substrings ending at a given index with a specific parity mask is equal to the number of prefixes ending at a previous index with that parity mask.
- Insight 3: To check if a substring is wonderful, we need to determine if at most one character has an odd count. This can be achieved by either having all characters with even counts (mask = 0) or by having only one character with an odd count (only one bit set in the mask).
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Hash Table, String, Bit Manipulation, Prefix Sum.
Companies
Asked at: DE Shaw.