40.给字符串s1、s2,在s1中找包含s2里所有字符的最小子串
2011-08-04 12:40
281 查看
题目:一串首尾相边的珠子(m个),有N种颜色,设计 一种算法,取出其中一段,要求包含所有N种颜色,并使长度最短。
给一个字符串s1,和一个小串s2,求算法能在s1中找到包含s2里所有字符的最小子串。比如:
s1 = “ADOBECODEBANC”
s2 = “ABC”
最小子串是 “BANC”,要求O(N)的算法。
此两题是一样的。
思路:
设置两个指针p1,p2,初始化指向s1串的开头。当p1, p2指针之间的s1子串字母包含s2全部字符时,p1++,当两个指针之间的子不完全包含s2中的全部字符时p2++(增加指针间距),与此同时记录合法包含子串的的最小串的起始位置。
在进行上述伸缩时,如何快速的记录s2串的包含情况?使用一个hash 表,记录字符的出现次数,当p1++时,将对应字母的计数减1,当p2++时,将对应字母的计数加1。
给一个字符串s1,和一个小串s2,求算法能在s1中找到包含s2里所有字符的最小子串。比如:
s1 = “ADOBECODEBANC”
s2 = “ABC”
最小子串是 “BANC”,要求O(N)的算法。
此两题是一样的。
思路:
设置两个指针p1,p2,初始化指向s1串的开头。当p1, p2指针之间的s1子串字母包含s2全部字符时,p1++,当两个指针之间的子不完全包含s2中的全部字符时p2++(增加指针间距),与此同时记录合法包含子串的的最小串的起始位置。
在进行上述伸缩时,如何快速的记录s2串的包含情况?使用一个hash 表,记录字符的出现次数,当p1++时,将对应字母的计数减1,当p2++时,将对应字母的计数加1。
#include<iostream> using namespace std; int FindMinSubString(char* s1, char* s2) { int hash_table[256]; /* 初始化 hash 表,s2中出现的字符标记为0, 其他标记为负数 */ for (int i=0; i<256; i++) { hash_table[i] = -1; } for (char* p = s2; *p != '\0'; p++) { hash_table[*p] = 0; } char* p1 = s1; char* p2 = s1; //最短长度 int min_len = 2100000000; //最小串的起止位置 char* min_p1 = s1; char* min_p2 = s1; //记录p1 p2之间的合法字符种类数 ,count == s2_len 包含s2 int count = 0; int s2_len = strlen(s2); /* 注意p2到达s1的结束位置后,不能结束 应当继续收缩,直到不含s2 */ while(*p2 !='\0' || s2_len==count) { //p1...p2不包含s2 if (count<s2_len) { //属于s2中出现的字符 if (hash_table[*p2] == 0) { count++; hash_table[*p2]++; } else if (hash_table[*p2] > 0) { hash_table[*p2]++; } p2++; } //不能用else 因为在上一个if语句中对count++; if(count == s2_len) { if (p2-p1 < min_len) { min_p1 = p1; min_p2 = p2; min_len = p2-p1; } //收缩 hash_table[*p1]--; if (hash_table[*p1] == 0) { count--; } p1++; } } //输出 while(min_p1 < min_p2) { cout<<*min_p1; min_p1++; } cout<<endl; return min_len; } int main() { char str1[]="abdddcaabc"; char str2[]="abc"; cout<<FindMinSubString(str1,str2); }
相关文章推荐
- 给字符串s1、s2,在s1中找包含s2里所有字符的最小子串
- PAT 1050. String Subtraction (20)(剔除s1中包含s2中的字符(s2中若有空格,s1中也得把空格剔除))
- 练习 2-5 编写函数 any(s1, s2),将字符串 s2 中的任一字符在字符串 s1 中第一次 出现的位置作为结果返回。如果 s1 中不包含 s2 中的字符,则返回-1。
- 要求在s1中删除所有s2的字符,要用最快的算法
- [LeetCode] minimum window 包含所有字符的最小子字符串
- 去除字符串s1中包含的s2中的字符后输出s1
- 在字符串S1中删除字符串S2中所包含的字符【转】
- 练习2-5 编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2的字符,则返回-1。
- 给定两个字符串s1,s2,要求判定s2是否能够被s1做循环移位得到的字符串包含。
- 练习 2-5 编写函数 any(s1, s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1。
- 练习 2-5 编写函数 any(s1, s2),将字符串 s2 中的任一字符在字符串 s1 中第一次 出现的位置作为结果返回。如果 s1 中不包含 s2 中的字符,则返回-1
- 练习 2-4 squeeze(s1, s2),将字符串s1 中任何与字符串s2 中字符匹配的字符都删除。
- 练习 2-5 编写函数 any(s1, s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1。
- 在字符串S1中删除字符串S2中所包含的字符
- 从文件读取字符串,并求出该字符串包含的字符集中所有字符的全部组合
- 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字
- 判断一个字符串里是否包含另一个字符串所有的字符
- 写一个函数,实现两个字符串的比较。即实现strcmp函数,s1=s2时返回0,s1!=s2时返回二者第一个不同字符的ASCII值。
- python删除所有的中文字符、非ASCII或非英文字符,检查字符串是否包含非ASCII
- 已知一个字符串,输出它包含字符的所有排列(permutations)