LeetCode每日一题
466.统计重复个数
题目描述
定义 str = [s, n]
表示 str
由 n
个字符串 s
连接构成。
- 例如,
str == ["abc", 3] =="abcabcabc"
。
如果可以从 s2
中删除某些字符使其变为 s1
,则称字符串 s1
可以从字符串 s2
获得。
- 例如,根据定义,
s1 = "abc"
可以从s2 = "ab***dbe***c"
获得,仅需要删除加粗且用斜体标识的字符。
现在给你两个字符串 s1
和 s2
和两个整数 n1
和 n2
。由此构造得到两个字符串,其中 str1 = [s1, n1]
、str2 = [s2, n2]
。
请你找出一个最大整数 m
,以满足 str = [str2, m]
可以从 str1
获得。
示例 1:
输入:s1 = "acb", n1 = 4, s2 = "ab", n2 = 2
输出:2
示例 2:
输入:s1 = "acb", n1 = 1, s2 = "acb", n2 = 1
输出:1
提示:
1 <= s1.length, s2.length <= 100
s1
和s2
由小写英文字母组成1 <= n1, n2 <= 106
思路
看不懂题😢,cv大法好
代码
C++
class Solution {
public:
int getMaxRepetitions(string s1, int n1, string s2, int n2) {
// 存匹配到下标p对应的s1、s2已匹配个数
unordered_map<int, pair<int, int>> mp;
int cnt1, cnt2 = 0;
// 存循环前的s1、s2匹配个数与一次循环的s1、s2匹配个数
int pre1, pre2, loop1, loop2;
// s2下标p
int p = 0;
// 打一个所有flag 如果有循环部分就true
bool flag = false;
// 匹配多个s1与s2
for(cnt1 = 1;cnt1<=n1;cnt1++){
for(int j = 0;j<s1.size();j++){
if(s1[j] == s2[p]){
p++;
// 到|s2|了就置0
if(p == s2.size()){
cnt2++;
p = 0;
}
}
}
// 找到s2重复下标 记录循环前的次数与一次循环的次数
if(mp.count(p)){
pre1 = mp[p].first;
pre2 = mp[p].second;
loop1 = cnt1 - pre1;
loop2 = cnt2 - pre2;
flag = true;
break;
}
else
mp[p] = {cnt1, cnt2};
}
// 如果没循环就直接返回s2次数除以n2
if(!flag)
return cnt2/n2;
// 循环了就算循环前和多次循环的s2次数 再暴力匹配剩余串的s2次数 加起来除以n2
int res = pre2 + (n1 - pre1)/loop1 * loop2;
for(int i = 0;i<(n1-pre1) % loop1;i++){
for(int j = 0;j<s1.size();j++){
if(s1[j] == s2[p]){
p++;
if(p == s2.size()){
res++;
p = 0;
}
}
}
}
return res/n2;
}
};