(LeetCode) Sword Pointer Offer II 015. Alle Anagramme in der Zeichenfolge

Finden Sie bei zwei gegebenen Zeichenfolgen s und p die Teilzeichenfolgen aller Anagramme von p in s und geben Sie den Startindex dieser Teilzeichenfolgen zurück. Die Reihenfolge der Antwortausgabe wird nicht berücksichtigt.

Anagramme beziehen sich auf Zeichenfolgen mit denselben Buchstaben, aber unterschiedlicher Anordnung.

Beispiel 1 :

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的变位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的变位词。

Beispiel 2 :

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的变位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的变位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的变位词。

Tipps :

1 <= s.length, p.length <= 3 * 104
s 和 p 仅包含小写字母

Antwort

Schiebefenster

  • Links und rechts markieren das Fenster, das linke ist geschlossen und das rechte ist offen [left, right).
  • Need markiert die erforderliche Anzahl jedes Zeichens, Win markiert die Anzahl der Zeichen im Fenster
  • valid wird verwendet, um die Anzahl der gültigen Zeichen im Fenster zu markieren. gültig + 1 nur, wenn die Anzahl der Zeichen A im Fenster genau der erforderlichen Anzahl der Zeichen A entspricht
  • Wenn valid gleich der erforderlichen Anzahl ( need.size) ist und die Fenstergröße ( right - left) gleich der erforderlichen Anzahl von Zeichen ist, fügen Sie left zur Ergebnismenge hinzu
#include "bits/stdc++.h"
using namespace std;

class Solution {
    
    
public:
    vector<int> findAnagrams(string s, string p) {
    
    
        vector<int> res;
        map<char, int> need, win;
        for (auto ch : p) {
    
    
            ++need[ch];
        }
        int left = 0;
        int right = 0;
        int valid = 0;
        while (right < s.size()) {
    
    
            // 需要增加窗口
            char ch = s[right];
            ++right;
            if (need.count(ch) != 0) {
    
     // 用"need[ch] != 0"会使得need的size+1
                ++win[ch];
                if (win[ch] == need[ch]) {
    
    
                    ++valid;
                }
            } else {
    
    
                left = right;
                valid = 0;
                win.clear();
            }
            // 需要收缩窗口
            while (valid == need.size()) {
    
    
                if (right - left == p.size()) {
    
    
                    res.push_back(left);
                }
                ch = s[left];
                ++left;
                --win[ch];
                if (win[ch] < need[ch]) {
    
      // 不要用"!=",也不要用"win[ch] == 0"
                    --valid;
                }
            }
        }
        return res;
    }
};

Beschreibung der Schiebefenstervorlage: https://labuladong.github.io/algo/2/19/26/

Supongo que te gusta

Origin blog.csdn.net/weixin_36313227/article/details/125602169
Recomendado
Clasificación