力扣1542 2024.5.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;
    }
};
posted @ 2024-05-22 19:18  训练师马文  阅读(15)  评论(0)    收藏  举报