博主主页: 码农派大星.
数据结构专栏:Java数据结构
数据库专栏:数据库
JavaEE专栏:JavaEE
软件测试专栏:软件测试
关注博主带你了解更多知识
解析:
先把 ss 和 tt 字符串转化为字符数组
char[] s = ss.toCharArray();
char[] t = tt.toCharArray();
再用数组模拟哈希表,统计各字符出现个数/频次, 为什么选数组模拟,而不是直接选用哈希表, 因为数组的时间复杂度为O(1), 哈希表时间复杂度虽然也是O(1),但是遇到哈希冲突时,时间复杂度就会变为O(n)
创建hash1数组 遍历 t数组字符出现个数/频次 , 并统计字符种类(kinds)
创建hash2数组 统计窗口中字符出现次数.频次
开始遍历 s数组 创建left right count 分别为0
进窗口前提:
char in = s[right] hash2[in]++
进窗口: 比较hash1和hash2字符是否相等, 如果相等种类 count ++
当 窗口hash2种类数 等于 hash1种类数时 说明此时窗口是一个可能覆盖的子串,但是我们要求的是最小子串
判断 如果 窗口长度 < minlen
则更新begin = left , minlen = right - left+1, 求包含所有t字符的最小窗口
出窗口前提: char out = s[left] ,left++
出窗口: if (hash2[out] == hash1[out]) count --
hash2[out]--
最后统计结果:
如果bengin 为起始-1 时 直接返回空串
否则 返回 begin位置 到 begin+minlen 位置字符串
复杂度分析:
代码:
class Solution {
public String minWindow(String ss, String tt) {
char[] s = ss.toCharArray();
char[] t = tt.toCharArray();
if(ss.equals(tt)) return ss;
int[] hash1 = new int[200]; //统计t字符出现的频次
int kinds = 0;
for(char ch : t){
if(hash1[ch] == 0) kinds++;
hash1[ch]++;
}
int[] hash2 = new int[200];//统计窗口中字符频次
int minlen = Integer.MAX_VALUE, begin = -1;
for(int left = 0, right = 0,count = 0; right < s.length; right++){
char in = s[right];
hash2[in]++;
//进窗口+维护
if(hash2[in] == hash1[in]) count++;
while(kinds == count){//判断
if(right - left+1 < minlen){//更新结果
begin = left;
minlen = right-left+1;
}
char out = s[left];
left++;
//出窗口+维护
if(hash2[out] == hash1[out]) count--;
hash2[out]--;
}
}
if(begin == -1) return new String();
else return ss.substring(begin,begin+minlen);
}
}