686. Repeated String Match

406 篇文章 0 订阅
406 篇文章 0 订阅

1,题目要求
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”).
给出两个字符串A和B,判断A需要重复几次,使得B成为A的子串。

2,题目思路
首先,对于这个问题,个人想到的是利用字符串前拼接,然后构成一个新串,判断是否是前后满足:
例如对于cdabcdab,两个字符串相连,可以构成:
cdabcdabcdabcdab,可以看到这样的拼接可以在中间构成一个新的字符串。
但是这种做法不可行,因为B的最前方和最后方未必能构成A(在本题的环境下)。
因此,另外一种办法是,首先,设置i代表每次循环开始,A开始的位置(设想”abcd”、”cdabcd”, 只有i=2才有可能比对成功。如果B确实是能够由A全部构成的,则利用一个j来对B遍历,最后j一定是B的长度。最后还需要进行一次余数判断,以此来确定需要多少个A才能构成B。
还有两种比较好的方法,见源码。

3,程序源码
方法1:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        for(auto i = 0, j = 0;i<A.size();i++)
        {
            for(j = 0;j<B.size() && A[(i+j)%A.size()] == B[j];j++);//确定B是否可以由A构成
            if(j == B.size())//此时 i 为 A 开始比对的位置,j显然是B的长度
                if((i+j)%A.size() == 0)//A="abcd", B="cdabcdab", 则i=2, j=B.size()=8,可以发现刚好补上了前面的值,所以只需要判断是否有余数即可
                    return (i+j)/A.size();
                else
                    return (i+j)/A.size()+1;
        }
        return -1;
    }
};

方法2:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
    //原理跟上面类似,但是在找B的开始时所用的方法有所不同
        string tmp = A + A;
        size_t pos = tmp.find(B.substr(0, A.size()));
        if(pos == string::npos)
            return -1;

        int count = 1;
        size_t i = 0;
        while(i < B.size()) {
            if(pos == A.size()) {
                pos = 0;
                ++count;
            }
            if(A[pos++] != B[i++])
                return -1;
        }        
        return count;
    }
};

方法3:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        int res = 1;
        string tmp = A;
        while (tmp.size() < B.size()) {
            tmp += A;
            res++;
        }
        if (tmp.find(B) != -1)  return res;
        tmp += A, res++;
        if (tmp.find(B) != -1)  return res;
        return -1;
    }
};

注:
size_t有点像unsigned int,但size_t和unsigned int有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值