原題網址:此處為連結
個人難度評價: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;
}
};