[抄题]:
给定一个字符串 s
和一个 非空字符串 p
,找到在 s
中所有关于 p
的字谜的起始索引。
字符串仅由小写英文字母组成,字符串 s 和 p 的长度不得大于 40,000。
输出顺序无关紧要.
样例
给出字符串 s = "cbaebabacd"
p = "abc"
返回 [0, 6]
子串起始索引 index = 0 是 "cba",是"abc"的字谜.
子串起始索引 index = 6 是 "bac",是"abc"的字谜.
[暴力解法]:
时间分析:
空间分析:
[思维问题]:
[一句话思路]:
先初始化,再统计p位之后的绝对值之和。
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
sliding window的原理是数数字,向右滑动时,count(r)++,count(l)--
[一刷]:
- 字符串处理一个个的字母时,要用.tochararray先把字符串转成数组
- det也是数组,absSum是其的绝对值求和
- det 有几个元素算几个,用for (int item : det)简写
- s.toCharArray();表示对方法的调用
- list一定要用linkedlist or arraylist来实现,不能直接复制粘贴
[二刷]:
- 特殊判断必须要写
- 搞清楚det的含义 = sc - pc pc增加,det = r - l r增加
- 在之后的数组中,都是计算cntS[] 数组的数量
- absSum要用Math.abs
[三刷]:
[四刷]:
[五刷]:
[五分钟肉眼debug的结果]:
[总结]:
根据表格进行联想
[复杂度]:Time complexity: O(n) Space complexity: O(n)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
[其他解法]:
[Follow Up]:
[LC给出的题目变变变]:
242. Valid Anagram 用deta求absSum
567. Permutation in String 两根指针?不懂
[代码风格] :
- cntS 才符合骆驼命名法
public class Solution { /** * @param s: a string * @param p: a string * @return: a list of index */ public List<Integer> findAnagrams(String s, String p) { //initialization List<Integer> ans = new LinkedList<>(); //corner case if (s.length() < p.length()) { return ans; } char[] sc = s.toCharArray(); char[] pc = p.toCharArray(); int[] cntS = new int[256]; int[] cntP = new int[256]; int[] det = new int[256]; //count first int absSum = 0; for (int i = 0; i < p.length(); i++) { cntS[sc[i]]++; cntP[pc[i]]++; det[sc[i]]++; det[pc[i]]--; } for (int item : det) { absSum += Math.abs(item); } if (absSum == 0) { ans.add(0); } //count rest for (int i = p.length(); i < s.length(); i++) { int r = sc[i]; int l = sc[i - p.length()]; System.out.println("sc[i]="+sc[i]); System.out.println("r="+r); cntS[r]++;//both s cntS[l]--; absSum = absSum - Math.abs(det[r]) - Math.abs(det[l]);//abs det[l]--; det[r]++; absSum = absSum + Math.abs(det[r]) + Math.abs(det[l]); if (absSum == 0) { ans.add(i - p.length() + 1); } } return ans; } }