深信服 9月14号笔试
第一题:
对于输入的字符串,存在3个或者以上的就消除掉,将原有的字串拼接,重复上述过程
输入: “222BCC111CB”
#include<string>
#include<vector>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
/*
对于输入的字符串,存在3个或者以上的就消除掉,将原有的字串拼接,重复上述过程
输入: "222BCC111CB"
输出:"BB"
*/
void Q1() {
string s = "222BCC111CB";
int s_size = s.size();
string res = "";
for (int i = 0; i < s_size; i++) {
int res_size = res.size();
if (res_size < 2) {
res += s[i];
}
else {
if (s[i] == res[res_size - 1] && s[i] == res[res_size - 2]) {
res.pop_back();
res.pop_back();
}
else {
res += s[i];
}
}
}
cout << res << endl;
return;
}
第二题:
leetcode 76. 最小覆盖子串
双指针模拟
/*
leetcode 76. 最小覆盖子串
双指针模拟
*/
void Q2(string s, string t) {
int s_size = s.size();
int t_size = t.size();
int cnt_t[128] = { 0 };
for (auto iter : t) {
cnt_t[iter]++;
}
int cnt_s[128] = { 0 };
int left = 0;
int cnt = 0;
string res = "";
for (int i = 0; i < s_size; i++) {
cnt_s[s[i]]++;
if (cnt_s[s[i]] <= cnt_t[s[i]]) cnt++; // 并不是每个与 t 中相同的字符都会造成 cnt++,只要够了就不会进这个if
else {
while (cnt_s[s[left]] > cnt_t[s[left]]) { // 这里的 while 就是查找最左边需要的字符,且合法的
cnt_s[s[left]]--;
left++;
}
}
if (cnt == t_size) { // 可能会有多次 满足条件 cnt == t_size,所以需要注意取最小长度的
if (res.empty()) res = s.substr(left, i - left + 1);
else if ((i - left + 1) < res.size()) res = s.substr(left, i - left + 1);
}
}
cout << res << endl;
return;
}
第三题:
leetcode 84. 柱状图中最大的矩形
单调递增栈+哨兵节点,取最大面积
/*
leetcode 84. 柱状图中最大的矩形
单调递增栈+哨兵节点,取最大面积
*/
void Q3(vector<int>& heights) {
heights.insert(heights.begin(), -1); // 左右哨兵,这个是为了防止 stk 为空
heights.push_back(-1); // 为了排出所有的数
int h_size = heights.size();
stack<int> upStk;
int res = 0;
for (int i = 0; i < h_size; i++) {
while (!upStk.empty() && heights[i] < heights[upStk.top()]) {
int height_index = upStk.top();
upStk.pop();
int temp_height = heights[height_index];
int left = upStk.top() + 1; // left 就是包括该数
int right = i - 1; // right 就是包括该数
res = max(res, temp_height*(right - left + 1));
}
upStk.push(i);
}
cout << res << endl;
}