目录
作者简介:
『LeetCode|每日一题』找到字符串中所有字母异位词
1.每日一题
2.解题思路
2.1 思路分析
2.2 核心代码
2.3 全部代码
2.4 易错点
一位20级的计科专业的新手,请各位大佬多多指教
个人主页:XiaoChen_Android
学习专栏:力扣专栏
发布日期:2022/8/6
原文链接--->点我
此题的难点在于不仅要找到异位词还必须找到该词开始的下标,所以此题用滑动窗口比较合适,因为窗口的长度是固定的(读者可以仔细思考一下下标应该怎么算)
S1:首先要创建两个数组,第一个存每次窗口中字母出现的频率,第二个存目标字符串中每个字母的频率,所以大小应都为26;
S2:只有当对应位置相同且出现频率相等时才说明此处为一个异位词,可以利用字母减去a的ASCII码值,这样每个字母的频率都会存到对应下标的数组中,即a存到下标为0的,b存到下标为1的,以此类推;
S3:难点是以 i 开始的窗口末尾对应下标是多少,举个例子(读者可以自己举例子发现规律,窗口的长度不变,为P.length()):
S4:下标的问题解决了,还有一个注意的地方,即每次窗口向右滑动,我们必须把上一次计算的字母频率减去1,否则会影响结果(这一步读者可以仔细斟酌,非常重要),实现起来其实也很方便,一行代码就够了;
S5:每次窗口滑动一次便判断一次是否和目标字符串相等,相等就把对应的下标 i 存起来即可。
for(int i = 0; i < l2; i++){
ss[s.charAt(i) - 'a'] += 1;
pp[p.charAt(i) - 'a'] += 1;
}
if(Arrays.equals(ss , pp)) list.add(0); //把第一组窗口单独判断
for(int i = 1; i < l1 - l2 + 1; i++){ //从i = 1开始为第二组窗口
ss[s.charAt(i - 1) - 'a'] -= 1; //去掉上一组窗口内的字母频率
ss[s.charAt(i + l2 - 1) - 'a'] += 1; //窗口末尾下标x = i + l2 - 1
if(Arrays.equals(ss , pp)) list.add(i);
}
class Solution {
public List findAnagrams(String s, String p) {
ArrayList list = new ArrayList<>();
int l1 = s.length();
int l2 = p.length();
if(l1 < l2) return list;
int[] ss = new int[26];
int[] pp = new int[26];
for(int i = 0; i < l2; i++){
ss[s.charAt(i) - 'a'] += 1;
pp[p.charAt(i) - 'a'] += 1;
}
if(Arrays.equals(ss , pp)) list.add(0);
for(int i = 1; i < l1 - l2 + 1; i++){
ss[s.charAt(i - 1) - 'a'] -= 1;
ss[s.charAt(i + l2 - 1) - 'a'] += 1;
if(Arrays.equals(ss , pp)) list.add(i);
}
return list;
}
}
类似题目推荐:
1.剑指offer专项练习
2.基础算法无论在研究生面试还是求职面试都是十分重要的一环,这里推荐一款算法练习资源:LeetCode;算法题只有多刷勤刷才能保持思路与手感,大家赶紧行动起来吧(温馨提示:常见的面试问答题库也很nice哦)
如果文章对你有帮助就支持一下噢,新手尝试,很多地方可能语言组织不当,不好的地方请各位大佬多多指教!