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.

&nbsp;
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.


&nbsp;
Constraints:


	1 &lt;= s.length &lt;= 105
	s consists only of digits.


from collections import defaultdict
class Solution:
    def longestAwesome(self, s: str) -> int:
        mask = 0
        index = defaultdict(lambda:float('-inf'),{0:-1})
        res = 0
        for i,c in enumerate(s):
            mask ^= (1<<(ord(c)-ord('0')))
            if index[mask] == float('-inf'):
                index[mask] = i
            res = max(res, i-index[mask])
			#when the palindrome has one odd numbers of digits
            for j in range(10):
                tmp_mask = mask^(1<<j)
                res = max(res, i-index[tmp_mask] if index[tmp_mask] != float('-inf') else 0)
        return res
class Solution {
    public int longestAwesome(String s) {
        Map<Integer,Integer>map=new HashMap<>();
        map.put(0,-1);
        
        int state=0;
        int ans=0;
        for(int i=0;i<s.length();i++){
            int bit=(1<<(s.charAt(i)-'0'));
            state ^=bit; //if odd freq then it becomes even or if even becomes odd
            
            if(map.containsKey(state))
               ans=Math.max(ans,i-map.get(state));
            
                for(int odd=0;odd<=9;odd++){ //become odds one by one
                    int mask=(1<<odd);
                    
                    Integer j=map.get(state^mask);
                    
                    if(j!=null)
                        ans=Math.max(ans,i-j);
                }
            
            if(!map.containsKey(state))
                map.put(state,i);
        }
        return ans;
        
    }
}
class Solution {
public:
    int longestAwesome(string s) {
        unordered_map<int,int> map;
        int mask = 0, maxL = 0;
        map[mask] = -1;

        for(int i=0; i<s.size(); ++i){
            int ch = s[i]-'0';
            mask^= (1<<ch);

            if(map.find(mask) != map.end()){
                maxL = max(maxL, i-map[mask]);
            }

            for(int x=0; x<=9; ++x){
                int newMask = mask^(1<<x);
                if(map.find(newMask) != map.end()){
                    maxL = max(maxL, i-map[newMask]);
                }
            }

            if(map.find(mask) == map.end()){
                map[mask] = i;
            }
        }
        return maxL;
    }
};
var longestAwesome = function(s) {
    // freq starts with 0:0 because 9 0s is also a state and if I come across a 
    // 0 down the road, that means that the whole array up to index i is of the required type
    let firstIndex={0:0}, result=-1, curr=0
    for (let i = 0; i < s.length; i++) {
       curr^= 1<<s[i]
       // Check if you have seen curr^0=curr before, 
	   // because that would make the inbetween elements' xor = 000000000
       if(firstIndex[curr]!==undefined)
            result=Math.max(result,i-firstIndex[curr]+1)
       // Check all the other xors, because that would make 
	   // the inbetween elements of the required type (100000000,010000000,......,000000001)
       for (let j = 0; j <10; j++) {
            let ele=1<<j
            if(firstIndex[curr^ele]!==undefined)
                //i-firstIndex[curr^ele] because on freq I saved
				//the smallest index where I last met curr^ele
                result=Math.max(result,i-firstIndex[curr^ele]+1)
       }
       if(firstIndex[curr]===undefined)
		   firstIndex[curr]=i+1// +1 cos 0th place is for my 0 state
    }
 
    return result
};
Find Longest Awesome Substring