字符串的排列
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 54 ms, 内存: 16.0 MB
// 思路:使用Java Stream来实现滑动窗口算法判断s2是否包含s1的某个变位词
// 1. 创建一个数组来存储s1的字符频率
// 2. 使用Stream API来遍历s2的字符,并在一个滑动窗口内维持字符频率
// 3. 如果窗口的大小大于s1的长度,则移除窗口最左边的字符
// 4. 比较窗口内的字符频率和s1的字符频率是否相同,相同则返回true
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.Arrays;
public class Solution {
public boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) return false;
int[] s1Map = new int[26];
int[] s2Map = new int[26];
s1.chars().forEach(c -> s1Map[c - 'a']++);
IntStream.range(0, s1.length()).forEach(i -> s2Map[s2.charAt(i) - 'a']++);
return IntStream.range(0, s2.length() - s1.length() + 1)
.anyMatch(i -> {
if (i > 0) {
s2Map[s2.charAt(i - 1) - 'a']--;
s2Map[s2.charAt(i + s1.length() - 1) - 'a']++;
}
return Arrays.equals(s1Map, s2Map);
});
}
}
解释
方法:
这个题解采用了滑动窗口的方法来判断s2是否包含s1的某个变位词作为子串。首先,通过一个长度为26的数组s1_count来统计s1中每个字符的出现次数。数组的索引对应从'a'到'z'的每个字符。接着,使用同样的方式,通过另一个长度为26的数组s2_count来动态地在s2上维护一个长度为s1长度的滑动窗口的字符出现次数。随着窗口在s2上从左到右滑动,检查当前窗口内的字符分布是否与s1相同。如果在任何时刻两个数组相等,说明s2中存在一个子串是s1的变位词,返回True。如果遍历完s2后没有找到任何匹配,返回False。
时间复杂度:
O(m)
空间复杂度:
O(1)
代码细节讲解
🦆
在滑动窗口算法中,如何确保s2_count数组在窗口移动过程中始终保持精确反映当前窗口内的字符频率?
▷🦆
题解中提到比较两个数组s1_count和s2_count是否相等的操作是O(1),但实际上不需要遍历整个数组来进行比较吗?
▷🦆
如果s1的长度大于s2的长度,这种情况下的返回值是什么?题解中是否考虑了这一边界情况?
▷