Minimum Window Substring 最小覆盖子串算法,minimumsubstring
分享于 点击 24515 次 点评:44
Minimum Window Substring 最小覆盖子串算法,minimumsubstring
题目
最小子串覆盖
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。
注意事项
如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回长度最小的子串。
说明在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
——不需要。
给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解 "BANC"
挑战要求时间复杂度为O(n)
分析
采用哈希的思想,记录字母出现次数。大小写字母的ASCII码不大于256,这样array['A']=3指A出现3次,array['B']=1指B出现了一次,以此类推,不能用常规意义上的定义array[0]=3表示A出现3次,这样就多了一层映射!故而数组的长度设置为256即可存放所有的字母。
首先预处理target,用256大小的整数数组tHash存储里面每个char出现的个数;
然后给定两个指标beg和end,一个移动start,也用一个256长的整数数组sHash记录从beg到end的这段字符串里面每个char出现的个数。如果sHash大于等于tHash,也就是说sHash里的每一位大于等于tHash里相应位置的值,找到当前start位置,为符合要求子串的起点,记录当前beg和end的长度,如果比已经记录的小,那么我们就选这个位最小窗口。记录beg和end。然后让start往前走一位。寻找下一个子串。
代码
/*
32 最小子串覆盖
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。
如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回长度最小的子串。
说明
在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
——不需要。
样例
给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解 "BANC"
*/
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
/**
* @param source: A string
* @param target: A string
* @return: A string denote the minimum window
* Return "" if there is no such a string
*/
string minWindow(string &source, string &target) {
// write your code here
if (source.empty() || target.empty())
return "";
int sLen = source.length(), tLen = target.length();
vector<int> sHash(256, 0), tHash(256, 0);
/*建立源串的映射,存储每个字符的出现次数*/
for (int i = 0; i < tLen; ++i)
{
++tHash[target[i]];
}//for
/*记录符合要求的子串的位置,以及找到的字符个数*/
int beg = -1, end = sLen, found = 0, minLen = sLen;
for (int i = 0, start = i; i < sLen; ++i)
{
++sHash[source[i]];
/*更新当前找到的字符个数*/
if (sHash[source[i]] <= tHash[source[i]])
++found;
/*判断是否找到所有字符*/
if (found == tLen)
{
/*将源串开头未出现在目标串的字符跳过*/
while (start < i && sHash[source[start]] > tHash[source[start]])
{
--sHash[source[start]];
++start;
}//while
/*找到符合要求子串的首尾位置start 与 i*/
if (i - start < minLen)
{
minLen = i - start;
beg = start;
end = i;
}//if
/*跳过该子串的开头位置,寻找下一个子串*/
--sHash[source[start++]];
--found;
}//if
}//for
/*如果beg值为-1,说明不存在这样的子串*/
if (beg == -1)
return "";
else
return source.substr(beg, end - beg + 1);
}
};
int main()
{
Solution s;
string source = "ADOBECODEBANC", target = "BANC";
cout << s.minWindow(source, target) << endl;
system("pause");
return 0;
}
GitHub源码相关文章
- 暂无相关文章
用户点评