本文共 2210 字,大约阅读时间需要 7 分钟。
给你一个字符串 s 和一个字符串 t。任务是从 s 中找出一个最短的子串,使得这个子串包含 t 中的所有字符。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
输入:s = "ADOBECODEBANC",t = "ABC"。输出:"BANC"。
输入:s = "a",t = "a"。输出:"a"。
你能设计一个在 O(n) 时间内解决此问题的算法吗?
##思路
使用滑动窗口(Sliding Window)技术来解决这个问题,这种技术允许在 O(n) 时间复杂度内完成任务。滑动窗口通过使用两个哈希表 window 和 needs 来追踪当前窗口内的字符及其出现次数,以及 t 中字符的出现次数。
具体步骤如下:
minLen 记录最小长度,左指针 l 和右指针 r,以及哈希表 window 和 needs。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、窗口指针 l 和 r、以及哈希表 window 和 needs。needs 哈希表:记录 t 中每个字符及其出现次数。r,逐步扩展窗口,直到包含 t 中所有字符。l 缩小窗口,寻找更短的子串。minLen 和起始位置生成并返回最小的子串,若未找到则返回空字符串。通过这种方法,可以在 O(n) 时间复杂度内解决问题,适用于大规模字符串处理。
转载地址:http://dpusz.baihongyu.com/