※高频、重点
字节(飞书)、百度等大厂测开高频面试题:最长不重复子串
. - 力扣(LeetCode)字节飞书面经里的高频题,没做出来,需要好好复习。
重点考察-滑动窗口这个概念,自学记录一下:
一、滑动窗口
滑动窗口本质是双指针。处理连续的 子 字符串/数组,如最长最短等问题。(下图以最长不重复子串为例子)
如上图,核心思想就是满足条件的话,让黑色指针右移动;如果当前条件不满足,白色指针右移动。同时可以记录最长长度。
当黑色指针无法移动时,白色指针移动,白指针移动后如果黑色能移动就移动黑色。同时一个变量记录最大长度。
同时,为了满足这种关系,需要用到set数据结构(不可有重复元素)
此类问题核心代码模板:
/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {
unordered_map<char, int> need, window;
for (char c : t) need[c]++;
int left = 0, right = 0;
int valid = 0; //其中 valid 变量表示窗口中满足 need 条件的字符个数,,如果 valid 和 need.size 的大小相同,则说明窗口已满足条件,已经完全覆盖了串 T。
while (right < s.size()) {
// c 是将移入窗口的字符
char c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
...
// 判断左侧窗口是否要收缩
while (window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}
二、实战
2.1字节(飞书)\百度一面:最长不重复子串-(再练习)
题目链接在开头,做为测开面试常见手撕题,必须要会做。
(0914学习了滑动窗口概念和set用法后才做出来了,需要再练),注意其中的set用法
set<char> ans;//根据类型定义,像vector
ans.count()//检查某个元素是否在set里,1在0不在
ans.insert();//插入元素
ans.erase()//删除某个指定元素
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int max1=0;//最小长度是0,空字符串情况
int black=0,white=0;
set<char> ans;
while(black!=int(s.length())){
if(!ans.count(s[black])){//如果不存在,存里面,black++
ans.insert(s[black]);
black++;
max1=max(max1,int(ans.size()));
}else{//存在的话删掉首部的,white++
ans.erase(s[white]);
white++;
}
}
return max1;
}
};
2.2哔哩哔哩:14、牛客:最长无重复子数组
最长无重复子数组_牛客题霸_牛客网 同类题,只不过字符串换成了数组,上面一道能做出来这道题也能做出来
class Solution {
public:
int maxLength(vector<int>& arr) {
int black=0,white=0;
set<int> s;
int max1=0;
while(black!=arr.size()){
if(!s.count(arr[black])){
s.insert(arr[black]);
black++;
max1=max(max1,int(s.size()));
}else{
s.erase(arr[white]);
white++;
}
}
return max1;
}
};
2.3 力扣上同类高频题:438. 找到字符串中所有字母异位词-不会,回头在练习
相当于,输入一个串 S
,一个串 P,找到 S
中所有 P 的排列,返回它们的起始索引。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char,int> need,window;
vector<int> ans;
for(char c:p){
need[c]++;
}
int left=0,right=0;
int v=0;
while(right<int(s.length())){
char c=s[right];
right++;
if(need.count(c)){
window[c]++;
if(window[c]==need[c]){
v++;
}
}
while(right-left>=int(p.length())){ //left右移,缩框
if(v==need.size()){
ans.push_back(left);
}
char d=s[left];
left++;
if(need.count(d)){
if(window[d]==need[d]){
v--;
}
window[d]--;
}
}
}
return ans;
}
};