class Solution {
public:
int numDifferentIntegers(string word) {
unordered_set s;
int n = word.size(), p1 = 0, p2;
while (true) {
while (p1 < n && !isdigit(word[p1])) {
p1++;
}
if (p1 == n) {
break;
}
p2 = p1;
while (p2 < n && isdigit(word[p2])) {
p2++;
}
while (p2 - p1 > 1 && word[p1] == '0') {
p1++;
}
s.insert(word.substr(p1, p2 - p1));
p1 = p2;
}
return s.size();
}
};
vector occ;
for (int l = 0, r = 0 ; r < n ; r++) {
//如果右指针的元素加入到窗口内后,根据题目判断进行滑动左指针
while (l <= r && check()) l++;
}
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector occ(128);
int n = s.size();
int res = 0;
// 移动右指针
for (int l = 0, r = 0; r <= n - 1; r++) {
// 如果右边界的数字已出现过
// 移动左边界,直至不出现
while (occ[s[r]] && l <= r) {
occ[s[l++]] = false;
}
occ[s[r]] = true;
res = max(res, r - l + 1);
}
return res;
}
};
固定长度的滑窗
class Solution {
public:
vector findRepeatedDnaSequences(string s) {
// 如果字符串长度小于10,直接返回空的vector
if (s.length() < 10) {
return vector();
}
unordered_set occ, res; // occ用于存储遍历过的子串,res用于存储重复的子串
for (int i = 0; i <= s.length() - 10; ++i) {
string subStr = s.substr(i, 10); // 截取长度为10的子串
if (occ.find(subStr) != occ.end()) res.insert(subStr); // 如果子串已存在于occ中,则添加到res
occ.insert(subStr); // 将当前子串添加到occ
}
return vector(res.begin(), res.end()); // 将res中的子串添加到向量中并返回
}
};
class Solution {
private:
vector win = vector(58, 0); // s 子串中不同字符的出现次数
vector tCnter = vector(58, 0); // t 中字符的出现次数 A65 -- Z122
bool check() {
// 覆盖:win中每个字符的数量大于等于t的数量
for (int i = 0; i < 58; i++) {
if (tCnter[i] > win[i]) return false;
}
return true;
}
public:
string minWindow(string s, string t) {
// 统计 t 中的字符出现次数
for (char c : t) tCnter[c - 'A']++;
// 把 s 转化为数组
vector cs(s.begin(), s.end());
int minLen = 1000010, st = -1;
// 滑窗模板
for (int l = 0, r = 0; r < cs.size(); r++) {
win[cs[r] - 'A']++;
// 有可能更新
while (l <= r && check()) {
// 窗口大小复合规则
if (r - l + 1 < minLen) {
minLen = r - l + 1;
st = l; // 记录起始位置
}
// 左指针右移动 l++
win[cs[l++] - 'A']--;
}
}
return st == -1 ? "" : s.substr(st, minLen);
}
};
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int res = 100010;
for (int l = 0, r = 0, sum = 0; r < nums.size(); ++r) {
sum += nums[r];
// 有可能更新
while (l <= r && target <= sum) {
res = min(res, r - l + 1);
sum -= nums[l--];
}
}
return res == 100010 ? 0 : res;
}
};
#include
#include
class Solution {
private:
std::vector s1count = std::vector(26, 0);
std::vector s2count = std::vector(26, 0);
bool check() {
for (int i = 0; i < 26; ++i) {
if (s1count[i] < s2count[i]) return false;
}
// 如果都是 >= ,代表已经覆盖
return true;
}
public:
bool checkInclusion(std::string s1, std::string s2) {
if (s1.length() > s2.length()) return false;
// 统计该窗口下出现次数
for (int i = 0; i < s1.length(); ++i) {
s1count[s1[i] - 'a']++;
s2count[s2[i] - 'a']++;
}
if (check()) return true;
for (int l = 0, r = s1.length(); r < s2.length(); ++r, ++l) {
s2count[s2[r] - 'a']++;
s2count[s2[l] - 'a']--;
if (check()) return true;
}
return false;
}
};
class Solution {
public:
int equalSubstring(string s, string t, int maxCost) {
int res = 0;
for (int l = 0, r = 0, cost = 0; r < s.length(); ++r) {
cost += abs(s[r] - t[r]);
while (l <= r && cost > maxCost) {
cost -= abs(s[l] - t[l]);
l++;
}
res = max(res, r - l + 1);
}
return res;
}
};
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
# 优先选择结束的早的区间
# 留下来可选的空间更大
# 按照区间结束时间进行排序
intervals.sort(key=lambda x: x[1])
pre = intervals[0][1]
cnt = 1
for i in range(1, len(intervals)):
# 如果当前区间的开始时间大于等于前一个区间的结束时间,不重叠
if intervals[i][0] >= pre:
cnt += 1
pre = intervals[i][1]
# 返回需要移除的区间数量
return len(intervals) - cnt
class Solution:
def findContentChildren(self, g, s):
# 最小的饼干喂给最小的孩子
# 对孩子和饼干进行排序
g.sort()
s.sort()
cnt = 0
i, j = 0, 0
# 遍历饼干
while i < len(s) and j < len(g):
# 如果当前饼干满足当前孩子的胃口,那么直接喂给孩子
# 孩子指针后移
if s[i] >= g[j]:
cnt += 1
j += 1
# 喂不饱则饼干指针后移
i += 1
# 返回满足的孩子数量
return cnt
class Solution {
public:
int maxProfit(vector& prices) {
int all = 0;
// 今天买明天卖,可行就把获利加入
for (int i = 1; i <= prices.size() - 1; ++i) {
if (prices[i] > prices[i - 1]) {
all += prices[i] - prices[i - 1];
}
}
return all;
}
};