1.无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
考察知识点:哈希表,滑动窗口
class Solution {
public:
//i表示字串起始位置,j表示子串终止位置。当未出现重复时,字符串的长度即为字符串的结束位置减去起始位置。
//出现重复时,重复字符位置如果在原起始位置前,则起始位置不用更新;如果在原起始位置后,则用重复字符的位置去更新起始位置。
int lengthOfLongestSubstring(string s) {
int maxlen=0;
unordered_map<char,int> mp;
for(int i=0,j=0;j<s.size();++j)
{
if(mp.count(s[j])>0)
{
i=max(i,mp[s[j]]);
}
maxlen=max(maxlen,j-i+1);
mp[s[j]]=j+1; //*
}
return maxlen;
}
};
2.最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
考察知识点:动态规划
用 P(i,j)表示字符串s的第i到第j个字母组成的串是否为回文串,状态转移方程为
class Solution {
public:
string longestPalindrome(string s) {
vector<vector<int>> dp(s.length(), vector<int>(s.length()));
string ans;
for (int L = 0; L < s.length(); ++L)
{
for (int i = 0; i + L < s.length(); ++i)
{
int j = i + L;
if (L == 0) dp[i][j] = 1;
else if (L == 1) dp[i][j] = (s[i] == s[j]);
else dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
if (dp[i][j] && L + 1 > ans.length())
ans = s.substr(i, L + 1);
}
}
return ans;
}
};
3.串联所有单词的子串
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
考察知识点:哈希表
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
if(s.size()==0||words.size()==0) return {};
int m=words.size(),n=words[0].size();
if(s.size()<m*n) return {};
unordered_map<string,int> mp,tmp;
for(int i=0;i<m;++i)
++mp[words[i]];
vector<int> v;
for(int i=0;i+m*n<=s.size();++i)
{
int j=i;
for(;j<i+m*n;j+=n)
{
string str=s.substr(j,n);
if(mp.find(str)==mp.end()) break;
++tmp[str];
}
if(j==i+m*n&&tmp==mp)
v.push_back(i);
}
return v;
}
};
4.覆盖最小子串
给你一个字符串s 、一个字符串t 。返回s中涵盖t所有字符的最小子串。如果 s 中不存在涵盖t所有字符的子串,则返回空字符串 。注意:如果s中存在这样的子串,我们保证它是唯一的答案。
考察知识点:哈希表、滑动窗口
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int> mp;
for(char c:t) ++mp[c];
int left = 0, cnt = 0, minlen = INT_MAX, start = left;
for (int i = 0; i < s.size(); ++i)
{
if (--mp[s[i]] >= 0) ++cnt; //*
while(cnt == t.size())
{
if (minlen > i - left + 1)
{
minlen = i - left + 1;
start = left;
}
if (++mp[s[left]] > 0) --cnt; //*
++left;
}
}
return minlen == INT_MAX ? "" :s.substr(start, minlen);
}
};
思路:
(1)用哈希表完成,由于匹配数组t可能存在重复值,所以map数值需要是int。
总体算法模拟音乐音量上下浮动,t 的元素个数就是音量高度,t 以外的其他元素都为 0,
(2)遍历 s 的过程中,遇到一个音则将其减少一个音量.(* t 数组以外的音量不可能大于 0)
搜索过程中,指定音量下降计数 cnt 增加,减小到 0 以下不算在内,
当减少总数等于 t 的总数时,所有数就齐了,计算长度。
(3)随后进行回退,如果是 t 以外的音,其增加不改变计数 cnt,直到遇到 t 中的音,
且该值在map中大于0时(区间中 t 的某一个音大于其原始的数量,它map的值可能会小于0???),
回退停止,继续向前搜索,重复 步骤 2。