本题中其实看着条件很多,但是仔细读一下会发现,前四个条件都是固定条件。然后我们再看题。?我们的暴力做法是遍历a数组的字符串a的下标起始下标,然后遍历b数组的字符串b的下标起始下标,进行判断,但是这样会超时,所以我们是不是可以优化查找b数组,那么我们这里就发现到了一个第五个条件-k <= j - i <=k,i - k>=j,j <= k + i,那么我们有了已知的i和k,那么可以根据绝对值的数学性质找到j,那么我们怎么找最快呢,可以将b数组的下标加入到set中,然后通过lower_bound和upper_bound去寻找j,如果有,先判断该a数组下标是否添加过,如果添加过那就跳过,没有添加过就加入到res数组中。
class Solution {
public:
//1.i范围已经定死了,查找a字符串的范围为0~s.size() - a.size();
//满足上述条件之后还有一个就是从i开始,长度也已经定死了,只能是这个长度
//2.s[i ~ (i + a.size() - 1)] == a
//3.j范围已经定死了,查找b字符串的范围为0~s.size() - b.size();
//满足上述条件之后还有一个就是从j开始,长度也已经定死了,只能是这个长度
//4.s[j ~ (j + b.size() - 1)] == b
//满足上述条件之后
//5.abs(j - i) <= k
int findAndRecord(string& source,string& target,vector<int>& positions)
{
int pos = source.find(target);
while (pos != std::string::npos)
{
positions.push_back(pos);
pos = source.find(target, pos + 1);
}
return positions.size(); // 返回找到的位置数量
}
bool st[110000];
vector<int> beautifulIndices(string s, string a, string b, int k)
{
memset(st,0,sizeof(st));
int i_index_max = s.size() - a.size();
int j_index_max = s.size() - b.size();//上述都是闭区间,下标
int i_size_max = a.size();//固定a字符串长度
int j_size_max = b.size();//固定b字符串长度
vector<int> a_index;//存放a字符串的起始下标
vector<int> b_index;//存放b字符串的起始下标
findAndRecord(s,a,a_index);
findAndRecord(s,b,b_index);
set<int> s_b_index;
vector<int> res;
for(int i = 0;i < b_index.size();i++) s_b_index.insert(b_index[i]);
for(int i = 0;i < a_index.size();i++) cout<<a_index[i]<<" ";
cout<<endl;
for(int i = 0;i < b_index.size();i++) cout<<b_index[i]<<" ";
cout<<endl;
for(int i = 0;i < a_index.size();i++)
{
//-k<=j - i<=k
int _i_index = a_index[i];
if(st[_i_index]) continue;
int zhen_j = _i_index - k;//j>=i-k
int fu_j = k + _i_index;//j<=k+i
auto it_lower = s_b_index.lower_bound(zhen_j);
if(it_lower != s_b_index.end())
{
if((abs(*it_lower - _i_index) <= k))
{
res.push_back(_i_index);
st[_i_index] = true;
}
}
auto it_upper = s_b_index.upper_bound(fu_j);
if(st[_i_index]) continue;
if(it_upper != s_b_index.end())
{
if((abs(*it_upper - _i_index) <= k))
{
res.push_back(_i_index);
st[_i_index] = true;
}
}
}
return res;
}
};