字符串的子串问题详解
来源:互联网 发布:oracle数据库参数 编辑:程序博客网 时间:2024/05/21 07:51
原答案 https://leetcode.com/problems/minimum-window-substring/#/solutions
字符串的子串问题,大多可以用下面的模版解决
int findSubstring(string s){ vector<int> map(128,0); int counter; // check whether the substring is valid int begin=0, end=0; //two pointers, one point to tail and one head int d; //the length of substring for() { /* initialize the hash map here */ } while(end<s.size()){ if(map[s[end++]]-- ?){ /* modify counter here */ } while(/* counter condition */){ /* update d here if finding minimum*/ //increase begin to make it invalid/valid again if(map[s[begin++]]++ ?){ /*modify counter here*/ } } /* update d here if finding maximum*/ } return d; }
这里我们可以分两种情况,一种是参数有两个字符串的,一种是参数只有一个字符串。两个字符串的题目一般要求我们在一个字符串中找另一个较短的字符串,可能是任意排列组合,也有可能是最小覆盖。参数只有一个字符串的题目一般要求我们在所给的字符串中找到符合某种要求的子串,比如只能有两个不同的字符,比如字符不重复。
1.参数为两个字符串的情况
例题:438. Find All Anagrams in a String
这道题跟我们之前的567题 很相似,不过这里我们改进做法,按模版的话复杂为O(n)。
首先套用模版,在初始化map时,把p中出现过的字符对应的位置加1。这里我们把count初始化为p.size,如果s中出现了在p中的字符,让count减一,如果count减到0,说明出现了p的一种排列。一般来说,参数是两个字符串的题,你要在长的字符串中找短的字符串,我们把count的值设为短字符串的长度。反之,在一个参数的题目中,我们把count初始化为0。
这道题本质上还是用到了slide window的思想,所以我们要保证,当窗口大小等于p的长度时,要让begin右移,同时维护map,让本来在begin减去的1加上。这里要注意,如果在begin的值在p中出现过,在淘汰这个值时,count也要+1,否则我们的计算没办法进行。详细版代码如下:
class Solution {public: vector<int> findAnagrams(string s, string p) { vector<int> indecies; vector<int> map(128, 0); for (int i = 0; i < p.size(); ++i) { map[p[i] - 'a']++; } int count = p.size(), begin = 0, end = 0; while(end < s.size()){ if(map[s[end] - 'a'] > 0)count--; map[s[end] - 'a']--;end++; if(count == 0)indecies.push_back(begin); //keep the window size //window size = end - begin ,end has been added 1 if(end - begin == p.size()){ //if s[begin] is is in p, count should ++ if(map[s[begin] - 'a'] >= 0)count++; map[s[begin] - 'a']++; //reset the map because s[begin] is begin++; //move the window to right } } return indecies; }};
例题:76. Minimum Window Substring
这道题要求最小的窗口,使其含有子串中所有字符。我们增加一个minWin记录最小窗口长度,head记录最小窗口起点。其它的与上题类似。这道题题目中没有规定是小写字母,因为我们申明为128的数组,所以可以直接取字符做下标,不需要 -'a', 上一题其实也不需要。
class Solution {public: string minWindow(string s, string t) { vector<int> hash(128, 0); for (int i = 0; i < t.size(); ++i) { hash[t[i]]++; } int begin = 0, end = 0, count = t.size(), minWin = INT_MAX, head = 0; while(end < s.size()){ if(hash[s[end++]]-- > 0)count--; while(count == 0){ if(end - begin < minWin){ minWin = end - begin; head = begin;} //判断begin处的元素在不在t中,hash[s[begin]] = 0说明在 //其实不会有>0的情况 if(hash[s[begin]] >= 0)count++; hash[s[begin]]++; begin++; } } return minWin == INT_MAX? "" : s.substr(head, minWin); }};
1.参数为一个字符串的情况
例题:3. Longest Substring Without Repeating Characters
一个字符串的题目,我们让count来表示出现的不满足条件的字符,如果count不等于0,那我们就需要调整begin的位置。
class Solution {public: int lengthOfLongestSubstring(string s) { vector<int> hash(128, 0); int begin = 0, end = 0, count = 0, maxLength = 0; while(end < s.size()){ if(hash[s[end]] != 0)count++; hash[s[end]]++; end++; while(count > 0){ //如果出现过两次,这里的值就大于1,要还原 if(hash[s[begin]] > 1)count--; hash[s[begin]]--; begin++; } maxLength = max(maxLength, end - begin); } return maxLength; } };
//待更
- 字符串的子串问题详解
- 字符串中最长子串的问题
- hdu5672 找字符串的子串问题
- 字符串的最长回文子串问题
- 字符串问题---字符串中数字子串的求和
- 最大的子字符串问题
- VB6求两个字符串最长公共子串的问题
- 从字符串中提取子串得到数组的问题
- 求两个字符串最长公共子串的问题
- 两字符串的最长公共子串问题
- 字符串中最长的回文子串问题
- C# 实现求一个字符串的子串问题
- 字符串问题---最小包含子串的长度
- 字符串的最长公共子序列问题
- 字符串的最长公共子序列问题
- 重复子串问题(三):输出一个字符串中出现频率最高的子串
- java 求解子数组子字符串的问题合集
- 重复子串问题(二):求一个字符串中连续出现次数最多的子字符串
- 单例模式
- 35. Search Insert Position
- ajax插件
- XML中>,<,&,',"的转义
- jvm-类加载器
- 字符串的子串问题详解
- 洗发牌程序2(用getpid取得进程识别码实现)
- android基础学习6——intent实现数据传递
- Spring Boot学习笔记-整合Jsp (二)
- Android开发命名规范和编码规范
- 关于tpshop5的单字母函数M,D。
- 在Ubuntu 14.04 LTS中添加和删除PPA软件源
- SVG defs元素
- 使用javabean把小写金额转换成大写金额