⭐算法入门⭐《哈希表》困难01 —— LeetCode 76. 最小覆盖子串
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《哈希表》困难01 —— LeetCode 76. 最小覆盖子串相关的知识,希望对你有一定的参考价值。
🙉饭不食,水不饮,题必须刷🙉
C语言免费动漫教程,和我一起打卡! 🌞《光天化日学C语言》🌞
LeetCode 太难?先看简单题! 🧡《C语言入门100例》🧡
数据结构难?不存在的! 🌳《画解数据结构》🌳
LeetCode 太简单?算法学起来! 🌌《夜深人静写算法》🌌
一、题目
1、题目描述
给定两个字符串
s
和t
。返回s
中包含t
的所有字符的最短子字符串。如果s
中不存在符合条件的子字符串,则返回空字符串 “” 。如果s
中存在多个符合条件的子字符串,返回任意一个。注意: 对于t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。
样例输入:s = "ADOBECODEBANC", t = "ABC"
样例输出:"BANC"
2、基础框架
- C语言版本 给出的基础框架代码如下:
char * minWindow(char *s, char *t) {
}
3、原题链接
( 1 ) (1) (1) LeetCode 76. 最小覆盖子串
( 2 ) (2) (2) 剑指 Offer II 017. 含有所有字符的最短字符串
二、解题报告
1、思路分析
1)遍历统计一遍,利用哈希记录有多少种不同的字符记录下来,并且记录每种字符个数;
2)然后利用 尺取法 进行区间贪心。
2、时间复杂度
- 每个字符只会遍历一次,所以总的时间复杂度为 O ( n ) O(n) O(n)。
3、代码详解
int hash[256];
char * minWindow(char *s, char *t) {
int cnt = 0, needCnt = 0;
int tlen = strlen(t);
int slen = strlen(s);
char *ret;
memset(hash, 0, sizeof(hash));
for(int i = 0; i < tlen; ++i) {
if(!hash[ t[i] ]) // (1)
++needCnt;
++ hash[ t[i] ];
}
int i = 0, j = -1;
int l = 0, r = -1, ans = 1000000; // (2)
int size = slen;
while(j < size - 1) { // (3)
++j;
if(--hash[ s[j] ] == 0) { // (4)
++cnt;
}
while(cnt == needCnt) { // (5)
if(j - i + 1 < ans) { // (6)
ans = j - i + 1;
l = i;
r = j;
}
if( ++hash[ s[i] ] > 0 ) { // (7)
--cnt;
}
++i;
}
}
ret = (char *)malloc(r - l + 1 + 1); // (8)
size = 0;
for(int i = l; i <= r; ++i) {
ret[size++] = s[i];
}
ret[size] = '\\0';
return ret;
}
-
(
1
)
(1)
(1)
hash
代表字符计数,如果为零,则字符种类计数器加一; - ( 2 ) (2) (2) 初始化区间为空区间;
- ( 3 ) (3) (3) 不断扩展右指针;
- ( 4 ) (4) (4) 每扩展一次,就更新计数;
- ( 5 ) − ( 7 ) (5) - (7) (5)−(7) 当所有字符都已经出现的情况,更新区间长度,并且扩展左区间缩小区间长度后再次统计;
- ( 8 ) (8) (8) 最后,生成一个满足条件的区间。
三、本题小知识
在 C语言中,可以采用 直接定址法 将 字符直接映射到长度为 256 的哈希数组中。
以上是关于⭐算法入门⭐《哈希表》困难01 —— LeetCode 76. 最小覆盖子串的主要内容,如果未能解决你的问题,请参考以下文章
⭐算法入门⭐《哈希表》中等01 —— LeetCode 525. 连续数组
⭐算法入门⭐《哈希表》简单01 —— LeetCode 387. 字符串中的第一个唯一字符
⭐算法入门⭐《哈希表》中等02 —— LeetCode 560. 和为K的子数组
⭐算法入门⭐《哈希表》简单02 —— LeetCode 41. 缺失的第一个正数