⭐算法入门⭐《哈希表》困难01 —— LeetCode 76. 最小覆盖子串

饭不食,水不饮,题必须刷

C语言免费动漫教程,和我一起打卡!
光天化日学C语言

LeetCode 太难?先看简单题!
C语言入门100例

数据结构难?不存在的!
画解数据结构

LeetCode 太简单?算法学起来!
夜深人静写算法

文章目录

  • 一、题目
    • 1、题目描述
    • 2、基础框架
    • 3、原题链接
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、本题小知识

一、题目

1、题目描述

  给定两个字符串st。返回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 的哈希数组中。


你可能感兴趣的:(《LeetCode算法全集》,数据结构,算法,leetcode,尺取法,双指针)