笔试题22——最小覆盖子串

题目描述:
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。即要求在源字符串s中找到长度最短的子串,这个子串包含目标字符串t中的所有字符,字符顺序没有要求。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “#”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
核心代码如下:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;

string subStrOfMin(string a, string b) {

	//定义一个vec,vec记录着当前滑动窗缺少b中哪几个字符,每个字符缺少多少个.
	//对于字符ch,vec[ch]表示的是当前滑动窗缺少几个ch
	//如果vec[ch]大于0,说明缺少vec[ch]个ch
	//如果vec[ch]小于0,说明滑动窗中富余|map[ch]|个ch(vec[ch]的绝对值个)
	//如果vec[ch]等于0,说明滑动窗中不缺少字符ch,也不富余字符ch	
	vector<int> vec(128, 0);
	//初始化将目标字符串b中所有字符放到vec中,代表缺少t中所有的字符
	for (int i = 0; i < b.size(); i++)
		++vec[b[i]];
	//for (auto ch : b)
		//++vec[ch];
	int length = b.size(); //设置计数器,记录当前滑动窗口缺少b中多少个字符
	int begin = 0, end = 0, head = 0;
	int len = 1000000;
	while (end < a.size()) {
		//当这个字符是滑动窗缺少的字符时,计数器减1
		if (vec[a[end++]]-- > 0)
			--length;
		while (length == 0) {
			if (end - begin < len) {
				len = end - begin;
				head = begin;
			}
			//当这个字符是滑动窗不缺也不富余的字符时,计数器加1
			if (vec[a[begin++]]++ == 0)
				++length;
		}
	}
	if (len < 1000000)
		return a.substr(head, len);
	else
		return "#";
	//return len == 1000000 ? "#" : a.substr(head, len);
}

int main() {
	string a, b;
	cin >> a >> b;
	cout << subStrOfMin(a, b) << endl;

	return 0;
}

参考链接:https://blog.csdn.net/sinat_35261315/article/details/78730717

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值