找出数组中的美丽下标 II(KMP,二分\双指针)

https://leetcode.cn/problems/find-beautiful-indices-in-the-given-array-ii/description/
给你一个下标从 \(0\) 开始的字符串\(s\) 、字符串 \(a\) 、字符串 \(b\) 和一个整数 \(k\)
如果下标 \(i\) 满足以下条件,则认为它是一个 美丽下标 :

  • \(0 <= i <= s.length - a.length\)
  • \(s[i..(i + a.length - 1)] == a\)
    • 存在下标\(j\)使得:
    • \(0 <= j <= s.length - b.length\)
    • \(s[j..(j + b.length - 1)] == b\)
    • \(|j - i| <= k\)
      以数组形式按 从小到大排序 返回美丽下标。

示例 1:
输入:s = "isawsquirrelnearmysquirrelhouseohmy", a = "my", b = "squirrel", k = 15
输出:[16,33]
解释:存在 2 个美丽下标:[16,33]。

  • 下标 16 是美丽下标,因为 s[16..17] == "my" ,且存在下标 4 ,满足 s[4..11] == "squirrel" 且 |16 - 4| <= 15 。
  • 下标 33 是美丽下标,因为 s[33..34] == "my" ,且存在下标 18 ,满足 s[18..25] == "squirrel" 且 |33 - 18| <= 15 。
    因此返回 [16,33] 作为结果。

示例 2:
输入:s = "abcd", a = "a", b = "a", k = 4
输出:[0]
解释:存在 1 个美丽下标:[0]。

  • 下标 0 是美丽下标,因为 s[0..0] == "a" ,且存在下标 0 ,满足 s[0..0] == "a" 且 |0 - 0| <= 4 。
    因此返回 [0] 作为结果。

提示:
\(1 <= k <= s.length <= 5 * 10^5\)
\(1 <= a.length, b.length <= 5 * 10^5\)
$s、a、和 b $只包含小写英文字母。

这个题就是kmp+二分,用kmp先把两个数组a,b在s中的位置处理出来

class Solution {
public:
    int nxt[500500];
    void GetNext(string s){
        nxt[0]=-1;
        int k=-1;
        int j=0;
        int m=s.size();
        while(j<m-1){
            if(k==-1||s[j]==s[k]){
                ++j;
                ++k;
                nxt[j]=k;
            }
            else{
                k=nxt[k];
            } 
        }
    }
    vector<int> kmp(string a,string b){
        int i=0;
        int j=0;
        int tot=0;
        vector<int> v;
        int n=a.size(),m=b.size();
        while(i<n){	
            if(j==-1||a[i]==b[j]){
                i++;j++;
            }
            else{
                j=nxt[j];
            }
            if(j==m){
                i--;j--; 
                v.push_back(i-m+1);
                j=nxt[j];
            }
        }
        return v;
    }
    
    vector<int> beautifulIndices(string s, string a, string b, int k) {
        GetNext(s);
        vector<int>pos_a;
        vector<int>pos_b;
        pos_a=kmp(s,a);
        pos_b=kmp(s,b);
        int n = pos_a.size(), m = pos_b.size();
        vector<int>ans;
        for(int i = 0; i < pos_a.size(); i++){
            int idx = lower_bound(pos_b.begin(), pos_b.end(), pos_a[i]) - pos_b.begin();
            if((idx < m && abs(pos_b[idx] - pos_a[i]) <= k) || (idx - 1 >= 0 && abs(pos_b[idx - 1] - pos_a[i]) <= k)){
                ans.push_back(pos_a[i]);
            }
        }
        return ans;
    }
};
posted @ 2024-01-17 11:46  lipu123  阅读(8)  评论(0编辑  收藏  举报