zoukankan      html  css  js  c++  java
  • 459. 重复的子字符串

    459. 重复的子字符串

    给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

    示例 1:

    输入: "abab"

    输出: True

    解释: 可由子字符串 "ab" 重复两次构成。
    示例 2:

    输入: "aba"

    输出: False
    示例 3:

    输入: "abcabcabcabc"

    输出: True

    解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/repeated-substring-pattern
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

     1.枚举

    class Solution:
        def repeatedSubstringPattern(self, s: str) -> bool:
            n = len(s)
            for i in range(1, n // 2 + 1):
                if n % i == 0:
                    if all(s[j] == s[j - i] for j in range(i, n)):
                        return True
            return False
    

    Python all() 函数

    2、字符串匹配

    class Solution:
        def repeatedSubstringPattern(self, s: str) -> bool:
            return (s + s).find(s, 1) != len(s)
    

      

    3、KMP字符串快速匹配算法,算法复杂度O(m+n);

    先计算next数组然后利用next数组

    class Solution {
    public:
        bool kmp(const string& query, const string& pattern) {
            int n = query.size();
            int m = pattern.size();
            vector<int> fail(m, -1);
            //计算next数组
            for (int i = 1; i < m; ++i) {
                int j = fail[i - 1];
                while (j != -1 && pattern[j + 1] != pattern[i]) {
                    j = fail[j];
                }
                if (pattern[j + 1] == pattern[i]) {
                    fail[i] = j + 1;
                }
            }
            //根据next数组实现跳转
            int match = -1;
            for (int i = 1; i < n - 1; ++i) {//因为是这个题目,所以需要从1开始,普通的匹配从0开始
                while (match != -1 && pattern[match + 1] != query[i]) {
                    match = fail[match];
                }
                if (pattern[match + 1] == query[i]) {
                    ++match;
                    if (match == m - 1) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        bool repeatedSubstringPattern(string s) {
            return kmp(s + s, s);
        }
    };
    

     

    4、优化的KMP

    class Solution:
        def repeatedSubstringPattern(self, s: str) -> bool:
            def kmp(pattern: str) -> bool:
                n = len(pattern)
                fail = [-1] * n
                for i in range(1, n):
                    j = fail[i - 1]
                    while j != -1 and pattern[j + 1] != pattern[i]:
                        j = fail[j]
                    if pattern[j + 1] == pattern[i]:
                        fail[i] = j + 1
                return fail[n - 1] != -1 and n % (n - fail[n - 1] - 1) == 0
            
            return kmp(s)

    5、Hash表做法

    统计出每种字母的个数,根据字母的个数判断每种字母可被均分的段数,也就是求除1外的因数
    将这些因数求交集,也就是整个字符串可能重复的次数。
    对每一种次数进行检验,如果都不满足,返回False

    class Solution(object):
        def repeatedSubstringPattern(self, s):
            """
            :type s: str
            :rtype: bool
            """
            hash_map = {}
            for c in s:
                if c not in hash_map:
                    hash_map[c] = 1
                else:
                    hash_map[c] += 1
            record = []
            for v in hash_map.values():
                record.append(set(self.getFactor(v)))
            temp = record[0]
            for i in range(1, len(record)):
                temp &= record[i]
            yes = [0] * len(temp)
            temp = list(temp)
            for j in range(len(temp)):
                length = len(s) / temp[j]
                start_list = [i * length for i in range(temp[j])]
                for i in range(len(start_list) - 1):
                    if s[start_list[i]:start_list[i] + length] != s[start_list[i + 1]:start_list[i + 1] + length]:
                        yes[j] = 1
                        break
            return 0 in yes
        def getFactor(self, n):
            result = []
            for i in range(2, n + 1):
                if n % i == 0:
                    result.append(i)
            return result
    

      

  • 相关阅读:
    Java学习--泛型
    java学习--自定义类的实例的大小比较和排序
    Java学习--枚举
    java学习--修饰符
    Java学习--变量
    POI--各种样式的XSSFCellStyle的生成
    POI 使用颜色字符串生成XSSFColor对象
    Others # 看到的一些創意 / 知乎不錯的提問/ Android安全
    RO # 不错站点
    Linux # Virtual Box VBoxGuestAdditions.iso
  • 原文地址:https://www.cnblogs.com/noticeable/p/14093646.html
Copyright © 2011-2022 走看看