zoukankan      html  css  js  c++  java
  • LeetCode 438. Find All Anagrams in a String

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

    Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

    The order of output does not matter.

    Example 1:

    Input:
    s: "cbaebabacd" p: "abc"
    
    Output:
    [0, 6]
    
    Explanation:
    The substring with start index = 0 is "cba", which is an anagram of "abc".
    The substring with start index = 6 is "bac", which is an anagram of "abc".
    

    Example 2:

    Input:
    s: "abab" p: "ab"
    
    Output:
    [0, 1, 2]
    
    Explanation:
    The substring with start index = 0 is "ab", which is an anagram of "ab".
    The substring with start index = 1 is "ba", which is an anagram of "ab".
    The substring with start index = 2 is "ab", which is an anagram of "ab".
    

    这道题要求统计原字符串中,与模板字符串构成Anagrams的子串有多少,所谓Anagrams,也就是在寻找pattern的一个全排列,但是这里不用这么麻烦,只需要统计patter中各个字母的出现次数,之后逐步滑动,判断原字符串中与子串等长的字符串个字母出现的次数,patter和源字符串统计结果相等,那就说明该位置匹配

     1 class Solution {
     2 public:
     3     vector<int> findAnagrams(string s, string p) {
     4         vector<int> sv(26, 0), pv(26, 0), res;
     5         if (s.size() < p.size())
     6             return res;
     7         for (int i =  0; i < p.size(); i++)
     8         {
     9             pv[p[i]-'a']++;
    10             sv[s[i]-'a']++;
    11         }
    12         if (sv == pv)
    13             res.push_back(0);
    14         for (int i = p.size(); i < s.size(); i++)
    15         {
    16             sv[s[i]-'a']++;
    17             sv[s[i-p.size()]-'a']--;
    18             if (pv == sv)
    19                 res.push_back(i - p.size() + 1);
    20         }
    21         return res;
    22     }
    23 };

    当然也可以做一些优化思路:

     1 class Solution {
     2 public:
     3     vector<int> findAnagrams(string s, string p) {
     4         if (s.empty()) return {};
     5         vector<int> res, m(256, 0);
     6         int left = 0, right = 0, cnt = p.size(), n = s.size();
     7         for (char c : p) ++m[c];
     8         while (right < n) {
     9             if (m[s[right++]]-- >= 1) --cnt;
    10             if (cnt == 0) res.push_back(left);
    11             if (right - left == p.size() && m[s[left++]]++ >= 0) ++cnt;
    12         }
    13         return res;
    14     }
    15 };

    这种方法只需要遍历一遍并且不需要比较两个向量的大小

  • 相关阅读:
    final-第十章
    路由器基本配置-命令行配置模式
    路由器基本配置-对话配置模式
    配置静态路由
    默认路由
    像素值的读写
    矩阵的基本元素表达
    创建Mat对象
    Mat类
    数学基础-3D空间的位置表示
  • 原文地址:https://www.cnblogs.com/dapeng-bupt/p/10412868.html
Copyright © 2011-2022 走看看