码迷,mamicode.com
首页 > 其他好文 > 详细

2021.1.29 刷题(重复的子字符串-KMP实现)

时间:2021-01-30 11:52:32      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:lse   题目   表示   多次   get   amp   bst   substring   problem   

题目链接:https://leetcode-cn.com/problems/repeated-substring-pattern
题目描述:
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。

示例 2:
输入: "aba"
输出: False

示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)

解题:
kmp算法中,求next数组尤其重要,在这一题中,实际就是求最长公共前后缀。在这里没有讲next数组右移一位,直接用前后缀表,所以如果 next[len - 1] != 0,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。
最长相等前后缀的长度为:next[len - 1]。
数组长度为:len。
如果len % (len - (next[len - 1])) == 0 ,则说明 (数组长度-最长相等前后缀的长度) 正好可以被 数组的长度整除,说明有该字符串有重复的子字符串。

class Solution {
public:
    vector<int> prefix_table(string pattern)
    {
        int n = pattern.size();
        vector<int> prefix(n, 0);  //prefix[k]表示以k结尾的最长公共前后缀的长度值
        int i = 0; //前缀指针
        int j = 1; //后缀指针
        for(;j < n; j++ )
        {
            
            while(i > 0 && pattern[i] != pattern[j])
            {
                i = prefix[i - 1];
            }
            if(pattern[i] == pattern[j]){
                i++;
                prefix[j] = i;
            }
        }
        return prefix;   
    }
    
    bool repeatedSubstringPattern(string s) {
        int len = s.size();
        vector<int> next;
        next = prefix_table(s);
        if(next[len - 1] != 0 && (len % (len - next[len - 1])) == 0)
            return true;
        else
            return false;

    }
};

2021.1.29 刷题(重复的子字符串-KMP实现)

标签:lse   题目   表示   多次   get   amp   bst   substring   problem   

原文地址:https://www.cnblogs.com/ZigHello/p/14345347.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!