给你两个字符串 s1
和 s2
,写一个函数来判断 s2
是否包含 s1
的排列。如果是,返回 true
;否则,返回 false
。
换句话说,s1
的排列之一是 s2
的 子串 。
示例 1:
输入:s1 = "ab" s2 = "eidbaooo" 输出:true 解释:s2 包含 s1 的排列之一 ("ba").
示例 2:
输入:s1= "ab" s2 = "eidboaoo" 输出:false
提示:
1 <= s1.length, s2.length <= 10^4
s1
和s2
仅包含小写字母
解法:双指针滑动窗口
class Solution {
public boolean checkInclusion(String s1, String s2) {
Map<Character, Integer> need = new HashMap<>();
Map<Character, Integer> window = new HashMap<>();
for (int i = 0; i < s1.length(); i++) {
need.put(s1.charAt(i), need.getOrDefault(s1.charAt(i), 0) + 1);
}
int valid = 0;
int left = 0;
int right = 0;
while (right < s2.length()) {
char c = s2.charAt(right);
if (need.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) + 1);
if (window.get(c).equals(need.get(c))) {
valid++;
}
}
// 窗口收缩
while (right - left + 1 == s1.length()) {
if (valid == need.size()) {
return true;
}
char delete = s2.charAt(left);
left++;
if (need.containsKey(delete)) {
if (window.get(delete).equals(need.get(delete))) {
valid--;
}
window.put(delete, window.get(delete) - 1);
}
}
right++;
}
return false;
}
}
时间复杂度
- 时间复杂度:O(m + n),m 和 n 分别是字符串s1,s2 的长度。
- 空间复杂度:O(k),k 是 s1 的字符集合的长度。