
解题思路:
- 滑动窗口: 使用滑动窗口来遍历 s 中所有长度为 p 的子串。
- 统计字符频率: 通过两个长度为 26 的数组分别统计窗口内字符和 p 中字符的出现次数,快速判断是否满足字母异位词条件。
Java代码:
class Solution {public List<Integer> findAnagrams(String s, String p) {int sLen = s.length(), pLen = p.length();if (sLen < pLen) {return new ArrayList<Integer>();}List<Integer> res = new ArrayList<>();int[] sCount = new int[26];int[] pCount = new int[26];for (int i = 0; i < pLen; ++i) {++sCount[s.charAt(i) - 'a'];++pCount[p.charAt(i) - 'a'];}if (Arrays.equals(sCount, pCount)) {res.add(0);}for (int i = 0; i < sLen - pLen; ++i) {--sCount[s.charAt(i) - 'a'];++sCount[s.charAt(i + pLen) - 'a'];if (Arrays.equals(sCount, pCount)) {res.add(i + 1);}}return res;}
}
复杂度分析:
- 时间复杂度: O(n + m),其中 n 是 s 的长度,m 是 p 的长度。
- 空间复杂度: O(1),使用两个固定长度为 26 的数组存储字符频率,空间与输入规模无关。

解题思路:
- 初始化哈希表: 用于存储前缀和的出现次数,初始时放入 {0: 1},以处理子数组从数组开头的情况。
- 遍历数组: 逐个计算当前前缀和,并检查哈希表中是否存在 当前前缀和 - k,若存在则累加对应的次数到结果。
- 更新哈希表: 将当前前缀和存入哈希表,维护其出现次数。
Java代码:
class Solution {public int subarraySum(int[] nums, int k) {Map<Integer, Integer> prefixMap = new HashMap<>();prefixMap.put(0, 1);int prefixSum = 0;int count = 0;for (int num : nums) {prefixSum += num;count += prefixMap.getOrDefault(prefixSum - k, 0);prefixMap.put(prefixSum, prefixMap.getOrDefault(prefixSum, 0) + 1);}return count;}
}
复杂度分析:
- 时间复杂度: O(n),其中 n 是数组长度。只需一次遍历数组。
- 空间复杂度: O(n),最坏情况下哈希表存储 O(n) 个不同的前缀和(例如所有元素互为相反数且和为 k)。