一、解题背景:
字符串的子串应该是常见的一类有关字符串的算法题目,这里我将leetcode的相关几道题汇总了一下,写了一些具体的思路和多种的求解方法。
二、问题求解:
3. 无重复字符的最长子串
class Solution {
public:
// 方法1:
int lengthOfLongestSubstring1(string s) {
unordered_map<char,int> mp; // 记录的是索引位置
int ans = 0, i = 0;
for (int j=0; j<s.size(); j++) {
if (mp.find(s[j])!=mp.end()) {
i = max(mp[s[j]], i);
}
ans = max(ans, j-i+1);
mp[s[j]] = j+1; // 保存对应字符后边的位置索引,可能作为下一次无重复字符串起点
}
return ans;
}
// 方法2:
int lengthOfLongestSubstring1(string s) {
unordered_map<char,int> mp; // 记录的是字符出现的次数
int ans = 0;
for (int i=0, j=0; j<s.size(); j++) {
mp[s[j]]++;
while (mp[s[j]]>1) { // 同样这个步骤也是为了找到相同字符的后一个位置
mp[s[i++]]--;
}
ans = max(ans, j-i+1);
}
return ans;
}
};
159. 至多包含两个不同字符的最长子串
class Solution {
public:
bool cmp(const pair<char, int> left,const pair<char, int> right) {
return left.second>right.second;
}
int lengthOfLongest2DisSubstring(string s) {
int ans = 1;
unordered_map<char, int> mp;
for (int j=0, i=0; j<s.size();) {
mp[s[j]] = i;
j++;
if(mp.size()==3) {
auto iter = max_element(mp.begin(), mp.end(), cmp); // 找到最小的value的键值对
i = iter->second+1;
mp.erase(iter);
}
ans = max(ans, j-i);
}
return ans;
}
};