459. Repeated Substring Pattern

LeetCode

  • 题目地址:https://leetcode.com/problems/repeated-substring-pattern/?tab=Description
  • 解题思路:简单描述一下题目,就是输入是一个字符串,问该字符串能否由它的子串多次复制而得。注释中包含了思路,主要参考https://discuss.leetcode.com/topic/67652/c-o-n-using-kmp-32ms-8-lines-of-code-with-brief-explanation/2
    考虑到在注释中显示效果不好,所以把也用文字描述一遍:
    首先i,j表示两个下标,i表示当前下标,j表示与i差一个循环子串的坐标。比如str=”abab”,i=2(a)的时候,j=0(a),并用dup的数组记录下来,要注意的是这里dup[3]=1,因为若是dup[i=2]=j=0的话,j走到2的时候发现循环不匹配的返回j=0,而s[j=0]和s[j=2]对应的字符相同,比较没意义,所以是i++和j++过后,再给dup赋值。判断s[i]与s[j]是否相等,有以下三种情况:

    1. 相等:如果相同,说明是重复的,那么i和j都往下走一步,同时给dup数组赋值
    2. 不相等且j=0:这时候str[i] != str[j],如果j=0即指向头,说明没找到重复的子串,这时候j不变,i继续往下走,如果到了重复的子串的开头,那么就会到情况1
    3. 不相等且j不为0:即原本已经找到重复的子串,但是再往下走没有满足重复子串的复制条件,比如”ababacababac”,一开始找到”ab”作为复制子串,后来是”ababac”,说明可能是有字符长度更大的子串作为重复子串,那么返回上一个循环中的位置

    最后考虑两种情况:一是整个字符串没有重复的子串,一直处于情况2所以dup[n]在结束的时候仍然等于0;还有一种情况或者说要求,最后一个子串的长度要被总长度整除,最后一个子串代表整个字符串遍历一遍后,最终确定的长度最大的重复子串(如果存在重复子串的话),n-dup[n]表示最后一个子串的长度

  • 代码如下:

    class Solution {
    public:
    bool repeatedSubstringPattern(string s) {
        int i = 1, j = 0, n = s.size();
        vector<int> dup(n+1,0);
        //i,j表示两个下标,i表示当前下标,j表示与i差一个循环子串的坐标
        //比如str="abab",i=2(a)的时候,j=0(a),并用dup的数组记录下来
        //要注意的是这里dup[3]=1,因为若是dup[i=2]=j=0的话,j走到2的时候发现循环不匹配的返回j=0,而s[j=0]和s[j=2]对应的字符相同,比较没意义,所以是i++和j++过后,再给dup赋值
        while (i < s.size()) {
            //情况1:如果相同,说明是重复的,那么i和j都往下走一步,同时给dup数组赋值
            if (s[i] == s[j]) {
                i++;
                j++;
                dup[i]=j;
            }
            //情况2:这时候str[i] != str[j],如果j=0即指向头,
            //说明没找到重复的子串,这时候j不变,i继续往下走,
            //如果到了重复的子串的开头,那么就会到情况1
            else if (j == 0) {
                i++;
            }
            //情况3:循环不匹配,且j不为0,即已经找到重复的子串,但是没有满足重复子串的复制条件,比如"ababacababac",说明可能是有字符长度更大的子串作为重复子串,那么返回上一个循环中的位置
            else {
                j = dup[j];
            }
        }
        //考虑两种情况:一是整个字符串没有重复的子串,一直处于情况2所以dup[n]在结束的时候仍然等于0;还有一种情况,最后一个子串的长度要被总长度整除,最后一个子串代表整个字符串遍历一遍后,最终确定的长度最大的重复子串(如果存在重复子串的话),n-dup[n]表示最后一个子串的长度
        return dup[n] && n % (n-dup[n]) == 0;
    }
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值