Find Longest Awesome Substring - Complete Solution Guide
Find Longest Awesome Substring is LeetCode problem 1542, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a string s . An awesome substring is a non-empty substring of s such that we can make any number of swaps in order to make it a palindrome. Return the length of the maximum length awesome substring of s . Example 1: Input: s = "3242415" Output: 5 Explanation: "24241" is the longest awesome substring, we can form the palindrome "24142" with some swaps. Example 2: Input: s = "12345678" Output: 1 Example 3: Input: s = "213123" Output: 6 Explanation: "213123" is the longest awesome sub
Detailed Explanation
The problem asks us to find the length of the longest substring of a given string 's' that can be rearranged to form a palindrome. Such a substring is called 'awesome'. The string 's' consists only of digits. A substring can be rearranged into a palindrome if and only if the count of each digit is even, or at most one digit has an odd count. The goal is to maximize the length of such a substring.
Solution Approach
The solution uses a prefix-based approach with a bitmask to keep track of the parity of each digit's count. It iterates through the string, updating the bitmask at each position. The algorithm maintains an array 'first_occurrence' to store the first index at which each mask occurs. By comparing the current mask with previously seen masks, we can determine if a substring is 'awesome' and update the maximum length accordingly.
Step-by-Step Algorithm
- Step 1: Initialize an array 'first_occurrence' of size 1024 (2^10) with all elements set to the length of the string 'n'. This array will store the first index at which each bitmask is encountered. Initialize first_occurrence[0] to -1, since a mask of 0 (all counts even) occurs before the string starts.
- Step 2: Initialize 'ans' (the maximum length) to 0 and 'mask' (the current bitmask) to 0.
- Step 3: Iterate through the string 's' from left to right (index 'i').
- Step 4: Update the current bitmask 'mask' by XORing it with (1 << digit), where 'digit' is the numeric value of the current character s[i]. This toggles the bit corresponding to the digit.
- Step 5: Check if the current mask has been seen before. Calculate the length of the substring ending at the current index 'i' that has the same mask, which would be a perfect palindrome: `i - first_occurrence[mask]`. Update 'ans' to be the maximum of its current value and this length.
- Step 6: Check if a mask differing by only one bit (i.e. one digit having an odd count) has been seen before. For each digit 'j' from 0 to 9, XOR 'mask' with (1 << j) to create a 'test_mask'. Calculate the length of the substring ending at the current index 'i' and having the test mask: `i - first_occurrence[test_mask]`. Update 'ans' to be the maximum of its current value and this length.
- Step 7: If the current mask has not been seen before (i.e., first_occurrence[mask] is still equal to the initial value 'n'), update first_occurrence[mask] to the current index 'i'.
- Step 8: After iterating through the entire string, return the value of 'ans'.
Key Insights
- Insight 1: A substring is awesome if it can be rearranged to form a palindrome. This means at most one digit can appear an odd number of times.
- Insight 2: We can use a bitmask to represent the parity (even or odd) of the counts of each digit. Each bit in the mask corresponds to a digit (0-9). A bit is set to 1 if the count of that digit is odd, and 0 if it's even.
- Insight 3: If two prefixes have the same bitmask, the substring between them has all even counts, meaning it is a palindrome. If the masks differ by only one bit, then only that digit's count is odd. Therefore, those prefixes form an 'awesome' substring.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Hash Table, String, Bit Manipulation.
Companies
Asked at: Directi.