11.8 leetcode打卡
438.找到字符串中所有字母异位词
原题链接:438. 找到字符串中所有字母异位词
题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
解题思路
滑动窗口
由题可知,我们只需在字符串
s
中找到和字符串p
所含字符完全相同(顺序可以不同)的子串,返回当前子串的起始索引即可。此处可以用空间大小为26(26个小写字母)的数组记录每个字母在字符串中出现的词频,然后判断两个数组是否相同
即可判断与
p
完全相同的子串依次枚举 从 0 ~
sLen
-pLen
(sLen
-pLen
之后开始的子串长度已经不满足,可直接滤掉)滑动窗口右移依次右移一位
左指针右移:左指针所指字母的词频-1
右指针右移:右指针右移后所指字母的词频+1
然后依次判断两个字符串词频数组是否相同,若相同则将右移后的左指针(索引)放入结果集中即可
代码实现
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
int sLen = s.length(), pLen = p.length();
if(sLen < pLen){ return vector<int>();}
vector<int> ans;
vector<int> sCol(26), pCol(26); //vector可以直接判等 不需要再遍历数组判等
for(int i = 0; i < pLen; ++ i){
++sCol[s[i] - 'a']; //记录每个字母出现的词频
++pCol[p[i] - 'a'];
}
if(sCol == pCol){
ans.emplace_back(0);
}
for(int i = 0; i < sLen - pLen; ++ i){
--sCol[s[i] - 'a']; //左指针右移
++sCol[s[i + pLen] - 'a']; //右指针右移
if(sCol == pCol){
ans.emplace_back(i + 1);
}
}
return ans;
}
};
3.无重复字符的最长子串
原题链接:3. 无重复字符的最长子串
题目描述
给定一个字符串
s
,请你找出其中不含有重复字符的 最长子串 的长度。
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
代码实现
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.length();
if(n < 2){ return n; }
unordered_set<char> res;
int ans = 0, left = 0;
for(int i = 0; i < n; ++ i){
while(res.find(s[i]) != res.end()){ //若当前字符可在表中找到
res.erase(s[left]); //则一直移除左侧指针所指字符,直到不重复
left ++;
}
ans = max(ans, i - left + 1); //判断每个字符的最大长度
res.insert(s[i]);
}
return ans;
}
};
128.最长连续序列
原题链接:128. 最长连续序列
题目描述
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
代码实现
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> set;
int ans = 0;
for(int& num : nums){
set.insert(num); //将所有元素插入无序表
}
for(int& num : nums){ //枚举每个元素
if(!set.count(num - 1)){ //此处过滤掉已经判断过的连续序列
int curNum = num;
int curAns = 1;
while(set.count(curNum + 1)){ //当curNum的后继一直在表中存在时,让其一直增长
++ curNum; //判断当前数字最长可连续到多少
}
curAns += (curNum - num); //当前数字的最长连续序列的长度
ans = max(ans, curAns); //比较每次得出最长的序列
}
}
return ans;
}
};