leetcode1147. 段式回文 滚动哈希

  • https://leetcode.cn/problems/longest-chunked-palindrome-decomposition/solution/

  • 你会得到一个字符串 text 。你应该把它分成 k 个子字符串 (subtext1, subtext2,…, subtextk) ,要求满足:

  • subtexti 是 非空 字符串
    所有子字符串的连接等于 text ( 即subtext1 + subtext2 + … + subtextk == text )

  • 对于所有 i 的有效值( 即 1 <= i <= k ) ,subtexti == subtextk - i + 1 均成立
    返回k可能最大值。

示例 1:

输入:text = "ghiabcdefhelloadamhelloabcdefghi"
输出:7
解释:我们可以把字符串拆分成 "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)"。
示例 2:

输入:text = "merchant"
输出:1
解释:我们可以把字符串拆分成 "(merchant)"。
示例 3:

输入:text = "antaprezatepzapreanta"
输出:11
解释:我们可以把字符串拆分成 "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)"。
 

提示:

1 <= text.length <= 1000
text 仅由小写英文字符组成

CODE

normal 贪心

// 贪心 
class Solution {
public:
    int res;
    int longestDecomposition(string text) {
        string s1, s2;
        int l = 0, r = text.size() - 1;
        while( l < r ){
            s1 += text[l]; 
            s2 = text[r] + s2; //构造字符串
            if( s1 == s2 ){ 
                res += 2;
                s1.clear(); //清空字符串
                s2.clear();
            }
            r --; //指针往中间移动
            l ++; 
        }
        if( s1.size() || s2.size() || text.size() % 2 == 1)
            res ++;
        return res;
    }
};

滚动哈希

  • 例如计算”apple“的哈希(a = 1,p = 16,l = 12,e = 5,131用于标记字符的位置,可以用其他数值替换):

  • hashCode(apple) = 1 * pow(131, 0) + 16 * pow(131, 1) + 16 * pow(131, 2) + 12 * pow(131, 3) + 5 * pow(131, 4)

  • 滚动哈希在对于字符串判断某一个长度的前后缀是否相同时,可以在O(1) 时间得到结果。

typedef unsigned long long ull; //防止溢出,如果溢出往往需要在hash时mod一个大数
class Solution {
public:
    int res;
    const int P=131;
    ull h[100010],p[100010];//h记录字符串哈希后的结果,p记录131的各个幂次的值用于计算h

    ull query(int l, int r){ 
        return h[r] - h[l-1] * p[r - l +1];//返回子串的哈希值
    }

    void init(string& s){
        p[0]=1;
        for ( int i = 0; i < s.size(); i ++ ){
            h[i+1] = h[i] * P + s[i];             
            p[i+1] = p[i] * P;                
        }
    }

    int longestDecomposition(string text) {
        int s1 = 0, s2 = text.size() - 1;
        init(text);
        int l = 0, r = text.size() - 1;
        while( l < r ){
            if( query(s1 + 1, l + 1) == query(r + 1, s2 + 1) ){ 
                res += 2;
                s1 = l + 1;//重新定位要比较的字符串
                s2 = r - 1;
            }
            r --;
            l ++;
        }
        if( s1 != l || s2 != r || text.size() % 2 == 1)
            res ++;
        return res;
    }
};

CG

  • https://leetcode.cn/problems/longest-chunked-palindrome-decomposition/solution/tan-xin-huo-zhe-mo-ni-you-zhu-shi-by-dre-5se0/

你可能感兴趣的:(笔记,哈希算法,算法)