[LeetCode 1542] Find Longest Awesome Substring

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 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 substring, we can form the palindrome "231132" with some swaps.

Example 4:

Input: s = "00"
Output: 2

 

Constraints:

  • 1 <= s.length <= 10^5
  • s consists only of digits.

This problem is very similar with LeetCode 1371 in regard with the parity representation in a bitmask. 

such a substring either has all even digit counts, or all even except one digit count that is odd. In fact, if we have a substring with all even counts and we have not reached the end of the input, we can always append 1 more character to make it longer. since we only care about the parity of each count and there are only 10 digits from 0 to 9, we can use bitmask + hash map to solve this problem. Keep a running bitmask that indicates each digit's parity, then we check for even length and odd length substrings. for even length, we only care about substring[0, i], because any other valid shorter substrings can be appended by 1 more character to make it be the odd case. If bitmask is 0, substring[0, i] is a valid answer candidate. for odd length, we check all 10 digits being the single odd count, and check if there is another bitmask with only this digit's value being different(even - even = even; odd - odd = even; even - odd = odd; odd - even = odd). If there is, we just found a odd length candidate. At last, if we have not seen the current bitmask before, save the mapping to the current index; otherwise we ignore it because we want to save the earliest appearance to get max length.

The runtime is O(10 * N), which is O(N).

class Solution {
    public int longestAwesome(String s) {
        Map<Integer, Integer> idxMap = new HashMap<>();
        idxMap.put(0, -1);
        int best = 1;
        int curr = 0;
        
        for(int i = 0; i < s.length(); i++) {
            int diff = s.charAt(i) - '0';
            int mask = 1 << diff;
            curr ^= mask;
            if(curr == 0) {
                best = Math.max(best, i + 1);
            } 
            else {
                //try each digit as the odd count digit
                for(int j = 0; j <= 9; j++) {
                    int k = 1 << j;
                    int copy = curr;
                    copy ^= k;
                    if(idxMap.containsKey(copy)) {
                        best = Math.max(best, i - idxMap.get(copy));
                    }                    
                }                   
            }        
            if(!idxMap.containsKey(curr)) {
                idxMap.put(curr, i);
            }
        }
        return best;
    }
}

Related Problems 

[LeetCode 1371] Find the Longest Substring Containing Vowels in Even Counts

原文地址:https://www.cnblogs.com/lz87/p/13507302.html