题一:最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
示例 2:
输入:s = “a”, t = “a”
输出:“a”
示例 3:
输入: s = “a”, t = “aa”
输出: “”
解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
class Solution {
public:
string minWindow(string s, string t) {
//利用滑动窗口的思路
unordered_map<char,int> need,window;//定义两个哈希表
for(char c:t) need[c]++; //此哈希表用来记录t字符串中,每个字符的个数
int left=0;
int right=0; //滑动窗口的起始位置
int valid=0;//记录满足要求的字符数
// 记录最小覆盖子串的起始索引及长度
int start = 0, len = INT_MAX;
while(right<s.length()){
char c = s[right];
right++; //右移窗口
if(need.count(c)){ //查找哈希表中key为c的键值对,返回其数量,为1,则找到,若没找到则返回0
window[c]++;
if(window[c]==need[c])
valid++;
}
//判断窗口是否需要收缩
while(valid==need.size()){
if(right-left<len){
start=left;
len=right-left;
}
char d = s[left]; //移出窗口的元素
left++; //左移窗口
if(need.count(d)){
if(window[d]==need[d])
valid--;
window[d]--;
}
}
}
return len==INT_MAX? "":s.substr(start,len);
}
};
滑动窗口
/* 滑动窗口算法框架 */
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;
while (right < s.size()) {
// c 是将移入窗口的字符
char c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
...
/*** debug 输出的位置 ***/
printf("window: [%d, %d)\n", left, right);
/********************/
// 判断左侧窗口是否要收缩
while (window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}
滑动窗口问题参考于:https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247485141&idx=1&sn=0e4583ad935e76e9a3f6793792e60734&scene=21#wechat_redirect
题二:无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size()==0) return 0;
int left=0;
int right=0; //滑动窗口的起始位置
//int len=0; //记录不含有重复字符的子串长度
int res=0; //记录不含有重复字符的最大字串长度
unordered_map<char,int> window;//哈希表
while(right<s.size()){
char c = s[right];//当前加入哈希表的元素
right++;
window[c]++;
while(window[c]>1){ //哈希表中无当前元素
char d = s[left];
left++;
window[d]--;
}
res=max(res,right-left);
}
return res;
}
};
题三:翻转二叉树
示例:
输入:
4
/
2 7
/ \ /
1 3 6 9
输出:
4
/
7 2
/ \ /
9 6 3 1
备注:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/invert-binary-tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==NULL) return NULL;
//利用先序遍历
TreeNode *p;
p=root->left;
root->left=root->right;
root->right=p;
invertTree(root->left);
invertTree(root->right);
return root;
}
};