Day8- 字符串part02

KMP算法的核心是构建一个部分匹配表(也称为最长相等前后缀表),该表可以用来确定在不匹配时应该跳到字符串的哪个位置。

对于这个问题,可以构建整个字符串的部分匹配表,然后检查表的最后一个值。

如果该值不为0,并且能被字符串长度减去这个值整除,那么字符串就是由它的一个子串重复构成的。

一、实现 strStr()

题目一:28. 找出字符串中第一个匹配项的下标

28. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

KMP算法思想 

/*
 * @lc app=leetcode.cn id=28 lang=cpp
 *
 * [28] 找出字符串中第一个匹配项的下标
 */

// @lc code=start
class Solution {
public:
    int strStr(string haystack, string needle) {
        if (needle.empty()) return 0;
        if (haystack.empty()) return -1;

        vector<int> lps = computeLPSArray(needle);
        int i = 0;  
        int j = 0;  

        while (i < haystack.size()) {
            if (haystack[i] == needle[j]) {
                i++;
                j++;
            }
            if (j == needle.size()) {
                return i - j;  
            } else if (i < haystack.size() && haystack[i] != needle[j]) {
                if (j != 0) {
                    j = lps[j - 1];
                } else {
                    i++;
                }
            }
        }
        return -1;  
    }

private:
    vector<int> computeLPSArray(const string& pattern) {
        vector<int> lps(pattern.size(), 0);
        int length = 0;  
        int i = 1;

        while (i < pattern.size()) {
            if (pattern[i] == pattern[length]) {
                length++;
                lps[i] = length;
                i++;
            } else {
                if (length != 0) {
                    length = lps[length - 1];
                } else {
                    lps[i] = 0;
                    i++;
                }
            }
        }
        return lps;
    }
};
// @lc code=end

二、 重复的子字符串 

题目一:459. 重复的子字符串 

459. 重复的子字符串

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

computeLPSArray 函数用于构建字符串的部分匹配表。

然后在 repeatedSubstringPattern 函数中,检查这个表的最后一个元素是否满足特定条件,来确定字符串是否由一个重复的子字符串构成。

如果这个值不为0,并且字符串长度可以被字符串长度减去这个值整除,那么这个字符串就是由一个子字符串重复多次构成的。

/*
 * @lc app=leetcode.cn id=459 lang=cpp
 *
 * [459] 重复的子字符串
 */

// @lc code=start
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        vector<int> lps = computeLPSArray(s);
        int n = s.size();
        int len = lps[n - 1];
        return len != 0 && n % (n - len) == 0;
    }

private:
    vector<int> computeLPSArray(const string& pattern) {
        int n = pattern.size();
        vector<int> lps(n, 0);
        int len = 0;
        int i = 1;

        while (i < n) {
            if (pattern[i] == pattern[len]) {
                len++;
                lps[i] = len;
                i++;
            } else {
                if (len != 0) {
                    len = lps[len - 1];
                } else {
                    lps[i] = 0;
                    i++;
                }
            }
        }
        return lps;
    }
};
// @lc code=end

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值