力扣1542 2024.5.22

训练师马文發表於2024-05-22

原題網址:此處為連結

個人難度評價: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;
    }
};