2022-11-15 14:25阅读: 31评论: 0推荐: 0

力扣-438-找到字符串中所有字母异位词

异位词就是长度组成字符和目标字符相同的字符串

第一想法是这样的

vector<int> findAnagrams(string s, string p) {
int n1 = s.size();
int n2 = p.size();
for (int i = 0; i < n1 - n2; i++) {
for (int j = i; j < i + n2; j++) {
// 判断接下来n2个字符是否覆盖了p中的出现的所有字符
}
}
}

这里是否覆盖怎么判断?用set?p中的字符可能重复吧,那就用hashset,value是字符出现的次数
每次copy一个hashset,value不为0就-1,等于0删除。结束如果hashset为空就是
但是很明显这样的时间复杂度和空间复杂度都差
而且最大长度3*104多半边界测试用例要超时,必须找到优化的方法

逐个匹配字符…

看题解是“滑动窗口”,理解一下

题解方法一的巧妙之处在于:

  1. 把字符比较转为了ASCII码数字
  2. 把逐个字符的相等比较转换为了词频数组的写相等比较
vector<int> findAnagrams(string s, string p) {
int sLen = s.size(), pLen = p.size();
if (sLen < pLen) return {};
vector<int> ans, sCount(26), pCount(26);
// 这里只统计了p长度的s词频
for (int i = 0; i < pLen; i++) {
++sCount[s[i] - 'a'];
++pCount[s[i] - 'a'];
}
// 通过直接判断数组巧妙地避免了挨个判断字符
if (sCount == pCount) ans.push_back(0);
for (int i = 0; i < sLen - pLen; i++) {
// 通过删除新增一个词频来实现滑动窗口
--sCount[s[i] - 'a'];
++sCount[s[i + pLen] - 'a'];
if (sCount == pCount) ans.push_back(i + 1);
}
return ans;
}

方法二则是更进一步,将逐个字符相等比较转为了所有字符的ASCII码值和相等
之所以这题能用“滑动窗口”也是基于了ASCII码

但是这里不能是简单的ASCII码加和,因为可能出现字符不一致但是ASCII码和一致的情况

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/16891981.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(31)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起