双指针(滑动窗口)
题目在这里
概述:给定s,p两字符串,在s串中找p的异位串的所有起始下标
常规思路:
由于是小写字母构成的字符串,那么用前缀和sum迭代统计p.len长度的字母,再与p字符串的桶存数组比较即是ans
class Solution { public: vector<int> findAnagrams(string s, string p) { vector<vector<int>> sum(s.length(), vector<int>(30, 0)); vector<int> ans; int ls = s.length(), lp = p.length(); vector<int> sp(30, 0); for (auto i : p) sp[i - 'a']++; for (int i = 0; i < ls; ++i) { for (int j = 'a' - 'a'; j <= 'z' - 'a' && i > 0; j++) sum[i][j] = sum[i - 1][j]; if (i >= lp) sum[i][s[i - lp] - 'a']--; sum[i][s[i] - 'a']++; if (i + 1 >= lp && sum[i] == sp) ans.emplace_back(i - lp + 1); } return ans; } };
但是常规归常规,复杂度为O(s.len+(s.len-p.len)*Σ),Σ=26
一般般,
故而进取之,
思路:
还是桶存p字符串的字母,在遍历s字符串中用l,r左右端点去维护这个桶的字母数,
当桶的长度满足p串长度,也即r-l+1==p.len时候,那么一定有l位置是异位串的起始下标。
code:
class Solution { public: vector<int> findAnagrams(string s, string p) { vector<int> sum(30, 0), ans; int ls = s.length(), lp = p.length(); if (ls < lp) return ans; for (auto i : p) sum[i - 'a']++; for (int l = 0, r = 0; r < ls; ++r) { --sum[s[r] - 'a']; while (sum[s[r] - 'a'] < 0) ++sum[s[l++] - 'a']; if (r - l + 1 == lp) ans.emplace_back(l); } return ans; } };
【Over】
搜索
复制

浙公网安备 33010602011771号