[leetcode] 686. Repeated String Match

题目:

Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1.

For example, with A = "abcd" and B = "cdabcdab".

Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").

Note:
The length of A and B will be between 1 and 10000.

代码:

#include<string>
class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        string temp = "";
        int cnt = B.size() / A.size() + 2;
        int i = 0;
        for(; i < cnt; i++){
            temp += A;
            if(temp.find(B) != string::npos) return i+1;
        }
        return -1;
    }
};

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        // 思路1:i代表每次循环开始,A开始的位置(设想"abcd"、"cdabcd", 只有i=2才有可能比对成功)
        /*for(int i = 0, j = 0; i < (int)A.size(); i++, j=0) {
            while(j==-1 || (j < (int)B.size() && A[(i+j)%A.size()]==B[j])) ++j;
            if(j == B.size()) {
                // 此时 i 为 A 开始比对的位置,j显然是B的长度,如:
                // A="abcd", B="cdabcdab", 则i=2, j=B.size()=8,可以发现刚好补上了前面的值,所以只需要判断是否有余数即可
                return (i+j)/A.size()+((i+j)%A.size()!=0?1:0);

            }
        }*/
        
        vector<int> next(B.size() + 1);
        next[0] = -1;
        for(int i = 0, j = -1; i < B.size(); ) {
            if(j == -1 || B[j] == B[i]) next[++i] = ++j;
            else j = next[j];
        }
        
        // 思路2:i的含义与思路1相同,代表每次循环开始,A开始的位置(哪怕是i=j-next[j])。
        //       当next[j]>=0时,此时意味着j可以跳过某些重复比对,直接从next[j]开始。
        //       
        //       关键在于:如何判断无论如何加倍A,也无法构成题目要求的串?
        //               当i>=A.size()时,则可以认为无需再比对下去。因为如果i>=A.size(),其实取模后的值本应该早就比对过了
        for(int i = 0, j = 0; i < (int)A.size(); i+=max(1,j-next[j]), j=next[j]) {
            while(j==-1 || (j < (int)B.size() && A[(i+j)%A.size()]==B[j])) ++j;
            if(j == B.size()) {
                // 此时 i 为 A 开始比对的位置,j显然是B的长度,如:
                // A="abcd", B="cdabcdab", 则i=2, j=B.size()=8,可以发现刚好补上了前面的值,所以只需要判断是否有余数即可
                return (i+j)/A.size()+((i+j)%A.size()!=0?1:0);

            }
        }
        return -1;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值