今天主要是把之前练过的滑窗专题重新拾起来。这块内容比较单一,也相对简单,今天练完就完了。
leetcode-1208 尽可能使字符串相等
这题因为是求子串而非子序列,顶层思想可以直接用贪心,不需要dp。底层方法是滑窗,首先构建cost数组,然后在csot数组上滑窗,要是窗口内的代价之和总是不大于maxCost。
class Solution {
public:
int equalSubstring(string s, string t, int maxCost) {
int n = s.size();
vector<int> cost(n);
for(int i = 0; i < n; ++i) cost[i] = abs(s[i] - t[i]);
int ans = 0, cost_sum_window = 0;
for(int l = 0, r = 0; r < n; ++r){
cost_sum_window += cost[r];
while(l <= r && cost_sum_window > maxCost){
cost_sum_window -= cost[l];
++l;
}
ans = max(ans, r - l + 1);
}
return ans;
}
};
leetcode-76 最小覆盖子串
这题基本上就是明示你用滑窗,虽然标着是hard但没啥好说的。
class Solution {
public:
bool check(const vector<int>& s, const vector<int>& t){
for(int i = 0; i < 58; ++i){
if(s[i] < t[i]) return false;
}
return true;
}
string minWindow(string s, string t) {
int m = s.size(), n = t.size();
if(n > m) return "";
vector<int> t_set(58);
for(char c : t) ++t_set[c - 'A'];
vector<int> s_window_set(58);
int length = 1e6, start_pos = -1;
for(int l = 0, r = 0; r < m; ++r){
++s_window_set[s[r] - 'A'];
while(l <= r && check(s_window_set, t_set)){
if(length > r - l + 1){
length = r - l + 1;
start_pos = l;
}
--s_window_set[s[l] - 'A'];
++l;
}
}
return start_pos == -1 ? "" : s.substr(start_pos, length);
}
};
leetcode-3 无重复字符的最长字串
滑窗模板题,没啥好说的。一般这种题用哈希表还是数组都能过,笔试不会卡这个时间,也就面试可能会问你怎么优化。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.size();
if(n == 1) return 1;
unordered_set<char> set;
int ans = 0;
for(int l = 0, r = 0; r < n; ++r){
while(l <= r && set.count(s[r])){
set.erase(s[l]);
++l;
}
set.emplace(s[r]);
ans = max(ans, r - l + 1);
}
return ans;
}
};