package leecode;
import java.util.HashMap;
import java.util.Map;
/**
* 567. 字符串的排列
*
* 给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
*
* 换句话说,s1 的排列之一是 s2 的 子串 。
*
*
* @author Tang
* @date 2021/12/3
*/
public class CheckInclusion {
/**
* 判断s2中是否包含s1的所有字符子串,并且要连续
* 与76题相似
* 采用滑动窗口
*
* @param s1
* @param s2
* @return
*/
public boolean checkInclusion(String s1, String s2) {
char[] all = s2.toCharArray();
char[] s = s1.toCharArray();
//初始化need列表
Map<Character, Integer> needMap = new HashMap<>();
for (char c : s) {
needMap.put(c, needMap.getOrDefault(c, 0) +1);
}
//初始化window列表
Map<Character, Integer> window = new HashMap<>();
//表示当前有几个元素满足 0 <= valid <= s.length
//当valid == s.length时
int valid = 0;
int left = 0;
int right = 0;
//执行窗口右移
while(right < all.length) {
char c = all[right];
right++;
//此时说明元素c正需要
//window中可以暂时存储过量的元素,反正最后也可以通过缩窗口调掉
if(needMap.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) +1);
if(window.get(c).equals(needMap.get(c))) {
valid++;
}
}
//如果这个c我不需要,那么进行缩左窗口试试能不能让这个c变成需要
//如果不能就会把left缩到right对其,再从此刻重来
while(left < right && right - left >= s.length) {
//尝试更新结果
if(valid == needMap.size()) {
return true;
}
char d = all[left];
left++;
if(needMap.containsKey(d)) {
if(window.get(d).equals(needMap.get(d))) {
valid--;
}
//把元素d干掉
window.put(d, window.get(d) - 1);
}
}
}
return false;
}
public static void main(String[] args) {
String s1 = "abcdxabcde";
String s2 = "abcdeabcdx";
new CheckInclusion().checkInclusion(s1,s2);
}
}