【LeetCode】 子字符串思路
在一些求字串含有固定字符最短串,含有不同字符最长子串等问题中,利用 vector<int> map(128, 0)可以解决
题一:最短给定子串
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC" Output: "BANC"
Note:
- If there is no such window in S that covers all characters in T, return the empty string
""
. - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
Seen this question in a real interview before?
思路:
利用map,将常用的128个ascall码都包含进去,然后将T里有的字符在map进行累加,并计数,然后在S里找子串,完全找到后计数为零,然后继续找,直到找到最短的子串。
class Solution { public: string minWindow(string s, string t) { vector<int> map(128,0); int counter=t.size(), begin=0, end=0, min_length=INT_MAX, head = 0; for(auto a : t) map[a]++; while(end<s.size()){ if(map[s[end++]]-- > 0) counter--; while(counter == 0){ if(min_length > end - begin) min_length = end - (head = begin); if(map[s[begin++]]++ == 0) counter++; } } return min_length == INT_MAX ? "" : s.substr(head, min_length); } };
模板
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; }
根据模板就可以在不同的子串题中进行应用,也不是为了死搬硬套,这个只是利用map解决的思路,像递归解决排列问题一样。
题二:最长可出现两次子串
int lengthOfLongestSubstringTwoDistinct(string s) { vector<int> map(128, 0); int counter=0, begin=0, end=0, d=0; while(end<s.size()){ if(map[s[end++]]++==0) counter++; while(counter>2) if(map[s[begin++]]--==1) counter--; d=max(d, end-begin); } return d; }
题三:最长无重复子串‘
输出长度
int lengthOfLongestSubstring(string s) { vector<int> map(128,0); int counter=0, begin=0, end=0, d=0; while(end<s.size()){ if(map[s[end++]]++>0) counter++; while(counter>0) if(map[s[begin++]]-->1) counter--; d=max(d, end-begin); //while valid, update d } return d; }
输出具体子串,这里加一个子串起始标志位就行,在更新长度时更新子串起始位就行
心有猛虎,细嗅蔷薇 转载请注明:https://www.cnblogs.com/ygh1229/