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


    题目链接: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;
    
        }
    };
    
  • 相关阅读:
    js对象写法
    IE6双边距bug及其解决办法
    图片轮播
    盒子水平和垂直同时居中方法
    选项卡切换
    针对IE6兼容png
    html5兼容
    sublime快捷键总结
    七种设计原则
    Git基本命令
  • 原文地址:https://www.cnblogs.com/ZigHello/p/14345347.html
Copyright © 2020-2023  润新知