原题网址:此处为链接
个人难度评价:1700
分析:很惊讶会又在力扣看到区域赛的几乎原题。此题加上一个哈希就是区域赛题目了。
回文其实你只需要关注奇偶性。那么你用前缀和,维护[0:i]区间内每个数的奇偶性,此时你可以发现[0:i]和[i:j]的前缀和异或之后,为0的位就说明[i:j]内此位为偶。(也就是两个前缀和相同)为什么?
因为当[0:j]的第x位为奇数时,如果[0:i]的第x位也是奇数,那么显然奇+偶=奇。偶数也是同理。
当然,回文串长度为奇数的时候是可以有一位为0的。因为本题情况太少(仅有十个数字),你可以枚举当前位数下某一位在回文串中为奇数。
源码:
// 1542
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
class Solution {
public:
int longestAwesome(string s) {
int n = s.size();
bitset<10> m[n+1];
unordered_map<bitset<10>, int> p;
int ans = 1;
int now = 1;
p[m[0]] = 0;
bitset<10> cur;
for (int i=0; i<n; i++){
m[i+1][s[i]-'0'] = 1;
m[i+1] ^= m[i];
if (p.find(m[i+1]) == p.end()){
p[m[i+1]] = i+1;
}
else{
ans = max(ans, i+1-p[m[i+1]]);
}
for (int j=0; j<=9; j++){
cur = m[i+1];
cur[j] = (cur[j])?0:1;
if (p.find(cur) != p.end())
ans = max(ans, i+1-p[cur]);
}
}
// for (int i=n; i>=1; i--){
// for (int j=1; j+i-1<=n; j++){
// now = (m[j-1] ^ m[j+i-1]).count();
// if (now <= 1){
// ans = i;
// return ans;
// }
// }
// }
return ans;
}
};
标签:1542,2024.5,奇数,int,前缀,力扣,回文
From: https://www.cnblogs.com/TrainerMarvin/p/18206936