代码随想录day9|实现strStr()、重复的子字符串

这篇具有很好参考价值的文章主要介绍了代码随想录day9|实现strStr()、重复的子字符串。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现strStr()

代码随想录day9|实现strStr()、重复的子字符串,数据结构,leetcode,动态规划一般的字符串匹配问题我们可以使用KMP算法来处理,当我们搜索文本串和模式串是否匹配的时候,我们先得到模式串的一个前缀表,其中前缀表中存放的内容是模式串的最长相等前后缀。例如文本串为:aabaabaafa,模式串为:aabaaf,那么文本串的前缀表就是010120。当我们开始搜索时,我们发现在模式串f字符不匹配,我们就f前缀表中前一个字符的前缀表中的数值,发现是2,那么我们就跳到模式串下标为2的字符,继续遍历字符串。对于aabaaf来说,在f处不匹配,就是最长相等后缀aa后面的一个字符f不匹配,那么我就可以跳到最长相等前缀aa后面的一个字符b来重新进行匹配,此时前缀表中记录的最长相等前后缀的长度就是这个字符串b的下标。我们首先需要先得到这个前缀表。

class Solution {
public:
    //得到模式串needle的前缀表
    void getNext(int* next,string& s)
    {
        int j = 0;//用j来表示最长前缀,但是同时j也表示最长前后缀的值
        next[0] = j;
        for(int i = 1;i < s.size();i++)//用i来表示最长后缀
        {
            while(j > 0 && s[i] != s[j])//前缀、后缀不相等的情况
            {
                j = next[j - 1];
            }
            if(s[i] == s[j])//前缀、后缀相等的情况
            {
                j++;
            }
            next[i] = j;//前后缀相等时,更新next[i]为j++的数值;不相等时,更新为next[i]为回退后的数组
        }
    }

    int strStr(string haystack, string needle) //haystack是文本串,needle是模式串
    {
        int next[needle.size()];//创建一个数组用来存放前缀表的内容
        getNext(next,needle);//得到前缀表
        int j = 0;
        for(int i = 0;i < haystack.size();i++)//用i来遍历文本串
        {
            while(j > 0 && haystack[i] != needle[j])
            {
                j = next[j - 1];//j回退到j-1所对应的下标处
            }
            if(haystack[i] == needle[j])
            {
                j++;
            }
            if(j == needle.size())
            {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }
};

重复的子字符

代码随想录day9|实现strStr()、重复的子字符串,数据结构,leetcode,动态规划

这道题的思路有两种,第一个思路就是用两个字符串s相加,结果就是s+s,当我们去掉最前面一个和最后面一个得到的字符串中能查询到字符串s,那就说明这个字符串由重复子串构成。这种思想称为移动匹配。实现这种思路我们需要调用库函数,因为库函数的内部实现原本就比较高,所以使用这种想法的时间复杂度比较高。

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string t = s + s;
        t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾
        if (t.find(s) != std::string::npos) return true; // r
        return false;
    }
};

 其中,对于t.find(s) != std::string::npos,npos可以表示string的结束位置,意思就是说如果在字符串t中找不到字符串s,就会返回nops。这是npos的一个用法。

这道题的另一种解法就是KMP算法。这里直接给出结论,数组长度剪去最长相等前后缀的长度就是第一个周期的长度,如果这个的长度可以被整除,那就说明整个数组是这个周期的循环。文章来源地址https://www.toymoban.com/news/detail-613877.html

class Solution {
public:
    //得到前缀表
    void getNext(string& s,int* next)
    {
        int j = 0;//最长前缀
        next[0] = 0;
        for(int i = 1;i < s.size();i++)
        {
            while(j > 0 && s[i] != s[j])
            {
                j = next[j-1];
            }
            if(s[i] == s[j])
            {
                j++;
            }
            next[i] = j;
        }
         
    }

    bool repeatedSubstringPattern(string s) {
        int next[s.size()];
        getNext(s,next);
        int len = s.size();
        if(next[len-1] != 0 && len % (len - (next[len - 1]))== 0)
        {
            return true;
        }
        return false;
    }
};

到了这里,关于代码随想录day9|实现strStr()、重复的子字符串的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 代码随想录Day50

    昨天因为准备面试所以咕咕了一天。今天继续学习动规算法,尽管背包问题已经结束但其中的各类思想仍需要进一步理解。 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两

    2023年04月14日
    浏览(49)
  • 代码随想录day01

    ● 思维不难,主要是考察对代码的掌控能力 ● 内存中的存储方式:存放在连续内存空间上的相同类型数据的集合 ● 数组可以通过下标索引获取到下标对应的数据 ● 数组下标从0开始 ● 因为内存空间地址连续,因此删除或增加元素的时候,难免移动其他元素地址 ● Java中的

    2024年02月13日
    浏览(46)
  • 代码随想录day11

    代码随想录day11

    20. 有效的括号   思路:这里用模拟栈的方法会更好理解,也就是我们每次遇到朝左方向的三种类型的时候,就加入相反方向的右括号到result栈中。由于栈是一个先进后出的方式,所以我们会有一个判断stack当前为不为空,和stack[-1]是不是和当前循环到的括号相同。如果说相同

    2024年02月13日
    浏览(16)
  • 代码随想录Day62

    今天继续学习单调栈解决相关问题。 nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。 对于每个 0 = i nums1.length ,找出满足 nums1

    2024年02月01日
    浏览(51)
  • 代码随想录day44

    完全背包 其实就是每个物品可以使用无数次,给我们一个容器,装满这个容器的最大价值是多少。 思路: 如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 完全背包的组合和排序 518. 零钱兑换 II 题目 给你

    2023年04月17日
    浏览(48)
  • 【代码随想录】刷题Day31

    【代码随想录】刷题Day31

    455. 分发饼干 贪心的思路就是:小的饼干尽量去匹配胃口小的孩子,这样才能实现尽可能多孩子吃到。 那么代码就很好写了: 1.排序g和s,这样方便查找小的数 2.饼干的位置不停遍历,对应我们需要一个ret代表当前孩子位置 3.如果当前位置为孩子的数量,说明ret记录下所有的

    2024年02月06日
    浏览(47)
  • 代码随想录day42(背包)

    2024年02月13日
    浏览(11)
  • 代码随想录day7

    目录 第454题.四数相加II 思路: 383. 赎金信 思路: 第15题. 三数之和 思路: 力扣题目链接 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0   示例 1: 输入:nums1 = [1,2

    2024年02月10日
    浏览(10)
  • 代码随想录day8

    目录 344.反转字符串 思路: 541. 反转字符串II 思路: 题目:剑指Offer 05.替换空格 思路: 151.翻转字符串里的单词 思路: 题目:剑指Offer58-II.左旋转字符串 思路: 力扣题目链接(opens new window) 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形

    2024年02月09日
    浏览(15)
  • 代码随想录day6

    一开始想着构建两个hash表,但如果后面字符串长的可能会超时 这里借用数组构建hash表,主要思想是26个字母组成的数组统计出现次数 如果有出现次数为非0,则说明有问题,可以加以利用作为判断条件 这里对乱序的子字符串先排序,排序后的结果是否一致可以作为分组的依

    2024年02月04日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包