博客
关于我
LeetCode 76. 最小覆盖子串
阅读量:531 次
发布时间:2019-03-09

本文共 2210 字,大约阅读时间需要 7 分钟。

描述

给你一个字符串 s 和一个字符串 t。任务是从 s 中找出一个最短的子串,使得这个子串包含 t 中的所有字符。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

注意

如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例1:

输入:s = "ADOBECODEBANC"t = "ABC"。输出:"BANC"

示例2:

输入:s = "a"t = "a"。输出:"a"

进阶问题

你能设计一个在 O(n) 时间内解决此问题的算法吗?

##思路

使用滑动窗口(Sliding Window)技术来解决这个问题,这种技术允许在 O(n) 时间复杂度内完成任务。滑动窗口通过使用两个哈希表 windowneeds 来追踪当前窗口内的字符及其出现次数,以及 t 中字符的出现次数。

具体步骤如下:

  • 初始化变量 minLen 记录最小长度,左指针 l 和右指针 r,以及哈希表 windowneeds
  • 填充 needs 哈希表,将 t 中的每个字符及其出现次数记录下来。
  • 移动右指针,逐步扩展窗口,直到包含 t 中所有字符。
  • 当窗口满足条件时,尝试通过移动左指针缩小窗口,寻找更短的有效子串。
  • 在缩小窗口的过程中,持续检查是否找到了更短的子串,并记录起始位置和长度。
  • 最终,从记录的位置生成并返回最小的子串。
  • 在实现过程中,需要注意:

    • 使用哈希表记录字符出现次数,确保能够快速判断字符是否满足需求。
    • 刚进入窗口时避免频繁遍历,减少额外时间复杂度。
    • 正确处理窗口扩展和收缩过程中的字符出现变化,确保计数准确。
    • 当窗口不满足条件时,及时停止,避免不必要的计算。

    通过以上步骤,可以有效找到满足條件的最短子串,或者判断其不存在并返回空字符串。

    解答代码

    #include 
    #include
    #include
    using namespace std;class Solution {public: string minWindow(string s, string t) { int minLen = INT_MAX; unordered_map
    window; unordered_map
    needs; for (char c : t) { needs[c]++; } int l = 0, r = 0, match = 0, res_start = 0; while (r != s.size()) { char c_right = s[r]; if (needs.count(c_right)) { window[c_right]++; if (window[c_right] == needs[c_right]) { match++; } } r++; while (match == needs.size()) { if (r - l < minLen) { res_start = l; minLen = r - l; } char c_left = s[l]; if (needs.count(c_left)) { window[c_left]--; if (window[c_left] < needs[c_left]) { match--; } } l++; } } return (minLen == INT_MAX) ? "" : s.substr(res_start, minLen); }};

    代码解释

  • 初始化变量:包括 minLen、窗口指针 lr、以及哈希表 windowneeds
  • 填充 needs 哈希表:记录 t 中每个字符及其出现次数。
  • 扩展窗口:移动右指针 r,逐步扩展窗口,直到包含 t 中所有字符。
  • 收缩窗口:在满足条件时,尝试通过移动左指针 l 缩小窗口,寻找更短的子串。
  • 记录最小长度:在缩小窗口的过程中,持续检查是否找到了更短的子串,并记录起始位置和长度。
  • 返回结果:根据 minLen 和起始位置生成并返回最小的子串,若未找到则返回空字符串。
  • 通过这种方法,可以在 O(n) 时间复杂度内解决问题,适用于大规模字符串处理。

    转载地址:http://dpusz.baihongyu.com/

    你可能感兴趣的文章
    VTK:PolyData之Outline
    查看>>
    VTK:PolyData之RemoveVertices
    查看>>
    VTK:Qt之SideBySideRenderWindowsQt
    查看>>
    VTK:RenderMan之PolyDataRIB
    查看>>
    VTK:Rendering之DiffuseSpheres
    查看>>
    VTK:Rendering之MotionBlur
    查看>>
    VTK:简单操作之FloatingPointExceptions
    查看>>
    VTK:Utilities之BrownianPoints
    查看>>
    VTK:Utilities之DenseArrayRange
    查看>>
    VTK:Utilities之FrameRate
    查看>>
    VTK:Utilities之PCADemo
    查看>>
    VTK:Utilities之VectorArrayUnknownLength
    查看>>
    VTK:Render之RenderView
    查看>>
    VTK:可视化之AlphaFrequency
    查看>>
    重复点击事件(仅限于路由)
    查看>>
    VTK:可视化之AnnotatedCubeActor
    查看>>
    VTK:可视化之Arbitrary3DCursor
    查看>>
    VTK:可视化之Arbitrary3DCursor
    查看>>
    VTK:可视化之BackfaceCulling
    查看>>
    VTK:可视化之LoopShrink
    查看>>