写代码的时候要认真,一旦出错了,debug是很痛苦的,这次是叹号又没加队,而且初始赋值错了
class Solution {
private:
int len1;
int len2;
public:
void dfs(int i, int j, vector<vector<char>>& biggrid)
{
if (biggrid[i][j] == '0')return;
biggrid[i][j] = '0';
dfs(i + 1, j, biggrid);
dfs(i - 1, j, biggrid);
dfs(i, j + 1, biggrid);
dfs(i, j - 1, biggrid);
}
int numIslands(vector<vector<char>>& grid) {
if (!grid.size()) return 0;
len1 = grid.size();
len2 = grid[0].size();
vector<vector<char>> biggrid(len1 + 2, vector<char>(len2 + 2,'0'));
for (int i = 1; i < len1 + 1; i++)
{
for (int j = 1; j < len2 + 1; j++)
{
biggrid[i][j] = grid[i - 1][j - 1];
}
}
int n=0;
for (int i = 1; i < len1 + 1; i++)
{
for (int j = 1; j < len2 + 1; j++)
{
if (biggrid[i][j] == '1')
{
dfs(i, j, biggrid); n++;
}
}
}
return n;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
auto head1 = new ListNode(0);
head1->next = head;
auto temp = head1;
while(temp->next)
{
if(temp->next->val==val)
{
temp->next = temp->next->next;
}
else
{
temp = temp->next;
}
}
return head1->next;
}
};
class Solution {
public:
bool judge(int n)
{
for(int i = 2;i*i<=n;i++)
{
if(n%i==0)return false;
}
return true;
}
int countPrimes(int n) {
int count = 0;
for(int i = 2; i<n;i++)
{
if(judge(i))count++;
}
return count;
}
};
class Solution {
public:
bool isIsomorphic(string s, string t) {
int lens = s.size();
int lent = t.size();
if(lens!=lent)return false;
unordered_map<char,char> mp;
unordered_map<char,char>::iterator iter;
for(int i = 0 ; i<lens ;i++)
{
char s1 = s[i];
if(mp.find(s1)==mp.end())
{
for(iter = mp.begin() ;iter != mp.end();iter++)
{
if(iter->second==t[i])return false;
}
mp[s1] = t[i];
}
else
{
if(mp[s1]!=t[i])return false;
}
}
return true;
}
};
下面这种做法看似正确,但是是不对的,因为这里其实是浅拷贝,复制了以后如果直接对其进行修改,会导致原来的也发生变化,可以重新进行浅拷贝赋值但是不能进行值和指针的修改
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
auto head1 = head;
head1->next = NULL;
head = head->next;
while(head)
{
auto temp = head;
head = head->next;
temp->next = head1;
head1 = temp;
}
return head1;
}
};
当新建一个空节点的时候,不能使用auto
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
auto cur = head;
while(cur)
{
auto temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
class Solution {
public:
bool dfs(vector<vector<int>>& board, vector<int>& vt, int i)
{
if(vt[i]==-1) return true;//已经访问过
else if (vt[i]==1)return false;//正在访问
else
{
vt[i]=1;
for(auto j : board[i])//这里必须用auto
{
if(!dfs(board, vt, j))return false;
}
vt[i]=-1;
return true;
}
//return true;
}
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
//0表示未访问,1表示正在访问,-1表示已经访问过
vector<vector<int>> board(numCourses);
for(auto p:prerequisites)//这里必须用auto因为不知道有多少个
{
board[p[1]].push_back(p[0]);//注意方向
}
vector<int> vt(numCourses,0);
for(int i = 0 ;i<numCourses;i++)
{
if(!dfs(board,vt,i))return false;
}
return true;
}
};
/*
* 应用:自动补全、给字符串按字典序排序
* 优势:1、找到具有同一前缀的全部键值。2、按词典序枚举字符串的数据集。
*/
class Trie {
private:
// 最多R个指向子节点的链接,其中每个链接对应字母表数据集中的一个字母,这里取26个英文字母,R=26。
Trie *child[26];
// 指定节点是对应键的结尾还是只是键前缀
bool isWord;
public:
/** Initialize your data structure here. */
// 构造函数
Trie() {
isWord = false;
for (int i=0;i<26;i++) {
child[i] = nullptr;
}
}
/** Inserts a word into the trie. */
// 插入键 时间复杂度O(m),m为键长。空间复杂度O(m),最坏的情况下新插入的键没有公共前缀。
// 通过搜索Trie树来插入键。从根开始搜索它对应于第一个键字符的链接。
void insert(string word) {
// 用于指向每一层节点,进行搜索的操作。
Trie *t = this;
// 遍历插入键的每一个字符
for(char c: word){
// 如果链接不存在,创建一个新节点,并将它与父节点的链接相连,该链接与当前的键字符相匹配
if (!t -> child[c-'a']) {
t->child[c-'a'] = new Trie();
}
// 链接存在,沿着链接移动到树的下一个子层。算法继续搜索下一个键字符
t = t->child[c-'a'];
}
// 直到到达键的最后一个字符,然后将当前节点标记为结束节点。此时的当前节点已经移动到键的最后字符所在的节点
t->isWord = true;
}
/** Returns if the word is in the trie. */
// 查找键 时间复杂度O(m),最坏的情况下m为键长。空间复杂度O(1)
bool search(string word) {
// 用于指向每一层节点,进行搜索的操作。
Trie *t = this;
// 遍历查找键的每一个字符
for (char c:word) {
// 如果链接不存在,查找失败
if (!t -> child[c - 'a']) {
return false;
}
// 链接存在,沿着链接移动到树的下一个子层。算法接续查找下一个键字符。
t = t->child[c - 'a'];
}
// 直到到达最后一个字符,返回该键字符节点的isWord,如果为false,待查键是Trie树中另一个键的前缀。
return t->isWord;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
// 查找Trie树中的键前缀
bool startsWith(string prefix) {
// 用于指向每一层节点,进行搜索的操作。
Trie *t = this;
// 遍历查找前缀的每一个字符
for (char c:prefix) {
// 如果链接不存在,查找失败
if (!t->child[c-'a']) {
return false;
}
// 链接存在,沿着链接移动到树的下一个子层。算法接续查找下一个键字符。
t = t->child[c - 'a'];
}
// 直到到达最后一个字符,由于是查找前缀,而不是整个键,所以返回true
return true;
}
};
作者:ichhYTTtiU
链接:https://leetcode-cn.com/problems/implement-trie-prefix-tree/solution/qian-zhui-shu-c-shu-ju-jie-gou-by-ichhytttiu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
if(nums.empty())return 0;
int sum = 0,res = INT_MAX,start = 0;
for(int i = 0 ;i<(int)nums.size() ;i++)
{
sum += nums[i];
while(sum>=s)
{
res = min(res, i-start+1);
sum -= nums[start];
start++;
}
}
return (res==INT_MAX)?0:res;
}
};
对于1的情况分类讨论,一次算,一次不算,dp表达式不变
class Solution {
public:
int rob(vector<int>& nums) {
//分两种情况,计算1的和不计算1的
//计算1的情况,这样最后一个不能要了
int len = nums.size();
if(len==0) return 0;
if(len == 1)return nums[0];
if(len ==2)return max(nums[0],nums[1]);
if(len==3)return max(nums[0],max(nums[1],nums[2]));
vector<int> dp1 = nums;
dp1[0] = nums[0];
dp1[1] = nums[0];
dp1[2] = max(nums[1],nums[0]+nums[2]);
for(int i = 3; i<len-1 ;i++ )
{
dp1[i] = max(dp1[i]+dp1[i-2],dp1[i-1]);
}
//不要第一个
vector<int> dp2 = nums;
dp2[0] = 0;
dp2[1] = nums[1];
dp2[2] = max(nums[1],nums[2]);
for(int i =3 ; i<len ; i++)
{
dp2[i] = max(dp2[i]+dp2[i-2],dp2[i-1]);
}
return max(dp1[len-2],dp2[len-1]);
}
};
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void dfs(int k,int n, vector<int>& ref,int sum,int p)
{
if(sum>n)return;
if(path.size()==k)
{
if(sum==n){res.push_back(path);}
return;
}
for(int i =p;i<=9;i++)
{
if(ref[i-1]==0)
{
ref[i-1]=1;
sum += i;
path.push_back(i);
dfs(k,n,ref,sum,i+1);
path.pop_back();
sum -=i;
ref[i-1]=0;
}
}
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<int> ref(9,0);
dfs(k,n,ref,0,1);
return res;
}
};
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int,int> m;
for(auto i:nums)
{
if( m[i]>=1 )return true;
else m[i]=1;
}
return false;
}
};
class Solution {
public:
vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
vector<pair<int,int>> h;
multiset<int> m;
vector<vector<int>> res;
//1、将每一个建筑分成“两个部分”,例如:[2,9,10]可以转换成[2,-10][9,10],我们用负值来表示左边界
for(const auto& b:buildings)
{
h.push_back({b[0], -b[2]});
h.push_back({b[1], b[2]});
}
//2、根据x值对分段进行排序
sort(h.begin(),h.end());
int prev = 0, cur = 0;
m.insert(0);
//3、遍历
for (auto i:h)
{
if (i.second < 0) m.insert(-i.second); //左端点,高度入堆
else m.erase(m.find(i.second)); //右端点,高度出堆
cur = *m.rbegin(); //当前最大高度高度
if (cur != prev) { //当前最大高度不等于最大高度perv表示这是一个转折点
res.push_back({i.first, cur}); //添加坐标
prev = cur; //更新最大高度
}
}
return res;
}
};
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_map<int,vector<int>> mp;
for(int i = 0 ;i<nums.size();i++)
{
if(mp.find(nums[i])==mp.end())
{
vector<int> temp = {i};
mp[nums[i]]=temp;
}
else
{
if(mp[nums[i]].size()>=1 && i-mp[nums[i]].back()<=k)return true;
mp[nums[i]].push_back(i);
}
}
return false;
}
};
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) {
return 0;
}
int maxSide = 0;
int rows = matrix.size(), columns = matrix[0].size();
vector<vector<int>> dp(rows, vector<int>(columns));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (matrix[i][j] == '1') {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
}
maxSide = max(maxSide, dp[i][j]);
}
}
}
int maxSquare = maxSide * maxSide;
return maxSquare;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximal-square/solution/zui-da-zheng-fang-xing-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
和求最大深度的方法类似,直接递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
if(!root)return 0;
return countNodes(root->left)+countNodes(root->right)+1;
}
};
class Solution {
public:
int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
int s1 = (C-A)*(D-B);
int s2 = (G-E)*(H-F);
int left = max(A,E);
int right = min(C,G);
int up = min(D,H);
int down = max(B,F);
if(left>right || up<down)return s1+s2;
return s1+s2-(right-left)*(up-down);
}
};
class Solution {
public:
int calculate(string s) {
stack<string> st;
int i = 0,j=0;
while (i<s.size())
{
string s1;
if (s[i] >= '0')
{
while (s[i] >= '0')
{
s1 += s[i++];
}
}
else
{
s1 = s[i++];
}
if (s1 == "(")
{
st.push("(");
}
else if (s1 == ")")
{
int temp = stoi(st.top());
st.pop(); st.pop();
if (!st.empty() && st.top() == "+")
{
st.pop();
int t = stoi(st.top()) + temp;
st.pop();
st.push(to_string(t));
}
else if (!st.empty() && st.top() == "-")
{
st.pop();
int t = stoi(st.top()) - temp;
st.pop();
st.push(to_string(t ));
}
else st.push(to_string(temp));
}
else if (s1 == "+")
{
st.push("+");
}
else if (s1 == "-")
{
st.push("-");
}
else if (s1 == " ")
{
continue;
}
else
{
if (st.empty() || st.top() == "(")st.push(s1);
else if (st.top() == "+")
{
st.pop();
int temp = (stoi(st.top())) + stoi(s1);
st.pop();
st.push(to_string(temp));
}
else if (st.top() == "-")
{
st.pop();
int temp = (stoi(st.top())) - stoi(s1);
st.pop();
st.push(to_string(temp));
}
}
}
return stoi(st.top());
}
};
class MyStack {
public:
//用一个队列实现
queue<int> qt;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
qt.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int len = qt.size();
while(len-1)
{
len--;
qt.push(qt.front());
qt.pop();
}
int temp = qt.front();
qt.pop();
return temp;
}
/** Get the top element. */
int top() {
return qt.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return qt.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root)return NULL;
auto r = invertTree(root->right);
auto l = invertTree(root->left);
root->right = l;
root->left = r;
return root;
}
};
递归就是把大问题最后递归成小问题,只要使二叉树的每个节点的左右子节点交换,最后整个树的就翻转了
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
dfs(root);
return root;
}
private:
void dfs(TreeNode* root){ //这是先序遍历,每一个节点,然后将这个节点的左右子节点翻转
if(root){
swap(root->left, root->right);
dfs(root->left);
dfs(root->right);
}
}
};
作者:zuo-10
链接:https://leetcode-cn.com/problems/invert-binary-tree/solution/c-shi-yong-swapdi-gui-die-dai-by-zuo-10/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在vs上能运行通
class Solution {
public:
int calculate(string s) {
vector<string> st;
int i = 0;
while (i < s.size())
{
string s1;
if (s[i] >= '0')
{
while (s[i] >= '0')
{
s1 += s[i++];
}
}
else
{
s1 = s[i++];
}
if (st.empty() || s1 == "+" || s1 == "-" || s1 == "*" || s1 == "/") { st.push_back(s1); }
else if (s1 == " ") {}
else
{
if (st.back() == "*")
{
st.pop_back();
int temp = stoi(st.back())*stoi(s1);
st.pop_back();
st.push_back(to_string(temp));
}
else if(st.back()=="/")
{
st.pop_back();
int temp = stoi(st.back()) / stoi(s1);
st.pop_back();
st.push_back(to_string(temp));
}
else
{
st.push_back(s1);
}
}
}
int res = stoi(st[0]);
for (i = 1; i < st.size(); i++)
{
if (st[i - 1] == "+")
{
res += stoi(st[i]);
}
else if (st[i - 1] == "-")
{
res -= stoi(st[i]);
}
}
return res;
}
};
特别注意里面溢出的情况,最好的解决方式就换个表达方式,尽量不要产生大的数
class Solution {
public:
vector<string> summaryRanges(vector<int>& nums) {
//for(int i = 0;i(nums[i]);
int i=1,j=0;
vector<string> res;
while(i<nums.size())
{
//while(i
while(i<nums.size() && nums[i]-1==nums[i-1])i++;
if(j==i-1)
{
res.push_back(to_string(nums[j++]));i++;
}
else
{
res.push_back(to_string(nums[j])+"->"+to_string(nums[i-1]));j=i;i++;
}
}
if(j==nums.size()-1)res.push_back(to_string(nums[j]));
return res;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int count = 0;
int res = 0;
void dfs(TreeNode* root, int k)
{
if(!root)return;
dfs(root->left,k);
count++;if(count==k){res = root->val;return;}
dfs(root->right,k);
}
int kthSmallest(TreeNode* root, int k) {
dfs(root,k);
return res;
}
};
class Solution {
public:
bool isPowerOfTwo(int n) {
if(n==1)return true;
if(n<=0)return false;
if(n>0 && n<1)
{
n = 1/n;
}
while(n>2)
{
if(n%2!=0)return false;
n /=2;
}
return true;
}
};
自己写的不仅复杂而且有检查不出的错误,因为peek和pop会导致栈的元素全部移到另一个栈中会颠倒顺序,所以每次进行这两个操作的时候都需要再重新倒回来,这会十分的复杂
下面这个实现非常简单,一个栈就用来进,一个就用来出,当要出的时候就从出站里面弹,如果出栈为空就把入栈的所有元素再放入出栈,而且pop操作时比peek多加了一步,pop里面还能再使用peek
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
input.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int temp = peek();
output.pop();
return temp;
}
/** Get the front element. */
int peek() {
if(output.empty()){
while(input.size()){
output.push(input.top());
input.pop();
}
}
return output.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return input.empty() &&output.empty();
}
stack<int> input, output;
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
int count = 0;
auto slow = head;
auto fast = head;
auto temp = head;
while(temp){count++;temp=temp->next;}
while(fast && fast->next)
{
slow= slow->next;
fast = fast->next->next;
}
if(count%2==1){slow =slow->next;}
ListNode* pre = NULL;
auto cur = slow;
while(cur)
{
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
slow = pre;
while(head && slow)
{
if(head->val != slow->val)return false;
head = head->next;
slow = slow->next;
}
return true;
}
};
利用二叉搜索树的性质
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root)return root;
if((root->val>=p->val && root->val<=q->val)||(root->val<=p->val && root->val>=q->val))return root;
if(root->val<=p->val && root->val<=q->val)return lowestCommonAncestor(root->right,p,q);
if(root->val>=p->val && root->val>=q->val)return lowestCommonAncestor(root->left,p,q);
return root;
}
};
当我们用递归去做这个题时不要被题目误导,应该要明确一点
这个函数的功能有三个:给定两个节点 p 和 q
如果 p 和 q 都存在,则返回它们的公共祖先;
如果只存在一个,则返回存在的一个;
如果 p 和 q 都不存在,则返回NULL
具体思路:
(1) 如果当前结点 root等于 NULL,则直接返回 NULL
(2) 如果 root 等于 p 或者 q ,那这棵树一定返回 pp 或者 qq
(3) 然后递归左右子树,因为是递归,使用函数后可认为左右子树已经算出结果,用 left和 right表示
(4) 此时若leftleft为空,那最终结果只要看 rightright;若 rightright 为空,那最终结果只要看 leftleft
(5) 如果 leftleft 和 rightright 都非空,因为只给了 pp 和 qq 两个结点,都非空,说明一边一个,因此 rootroot 是他们的最近公共祖先
(6) 如果 leftleft 和 rightright 都为空,则返回空(其实已经包含在前面的情况中了)
时间复杂度是 O(n)O(n):每个结点最多遍历一次或用主定理,空间复杂度是 O(n)O(n):需要系统栈空间
作者:Wilson79
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/c-jing-dian-di-gui-si-lu-fei-chang-hao-li-jie-shi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return NULL;
if(root == p || root == q)
return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left == NULL)
return right;
if(right == NULL)
return left;
if(left && right) // p和q在两侧
return root;
return NULL; // 必须有返回值
}
};
作者:Wilson79
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/c-jing-dian-di-gui-si-lu-fei-chang-hao-li-jie-shi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这道题本来开始想的是遍历一次求所有位置的左积,再遍历一次求所有位置的右积,再遍历一次求左积*右积
大概是O(3n),但是其实可以一次遍历完成,每个值先不着急乘是左右的乘机乘积,可以先左边乘到这里,等一会右边再乘到这里,十分巧妙
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n=nums.size();
int left=1,right=1; //left:从左边累乘,right:从右边累乘
vector<int> res(n,1);
for(int i=0;i<n;++i) //最终每个元素其左右乘积进行相乘得出结果
{
res[i]*=left; //乘以其左边的乘积
left*=nums[i];
res[n-1-i]*=right; //乘以其右边的乘积
right*=nums[n-1-i];
}
return res;
}
};
作者:ooolize-2
链接:https://leetcode-cn.com/problems/product-of-array-except-self/solution/yi-ci-bian-li-qiao-miao-cun-chu-he-ji-suan-zuo-ji-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
if(k == 0) return res;
deque<int> window; //双端队列,从队头到队尾 依次存 窗口内最大元素的index ~ 最小元素的index
int right = 0;
while(right < nums.size()){ //后续,窗口每右移一次,都会产生一个最大值[队列头位置的元素]
if(!window.empty() && window.front() <= right - k){ //队头不在窗口范围内
window.pop_front();
}
while(!window.empty() && nums[right] > nums[window.back()]){ //待入队元素比队尾元素大
window.pop_back();
}
window.push_back(right);
right++;
if(right >= k) res.push_back(nums[window.front()]);
}
return res;
}
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty())return false;
int len1 = matrix.size();
int len2 = matrix[0].size();
int i=len1-1,j=0;
while(i>=0 && j<len2)
{
if(target==matrix[i][j])return true;
else if(target<matrix[i][j])
{
i--;
}
else
{
j++;
}
}
return false;
}
};
class Solution {
public:
bool isAnagram(string s, string t) {
unordered_map<char,int> ms,mt;
for(auto s1:s)ms[s1]++;
for(auto t1:t)mt[t1]++;
return ms==mt;
}
};