5637.判断字符串的两半是否相似
模拟
就是麻烦点,第二遍复制粘贴就可以了。
class Solution {
public:
bool halvesAreAlike(string s) {
map<char,int> a;
map<char,int> b;
int n=s.size();
int cnt1=0,cnt2=0;
for(int i=0;i<n/2;i++)
{
if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u'||s[i]=='A'||
s[i]=='E'||s[i]=='I'||s[i]=='O'||s[i]=='U')
cnt1++;
}
for(int i=n-1;i>=n/2;i--){
if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u'||s[i]=='A'||
s[i]=='E'||s[i]=='I'||s[i]=='O'||s[i]=='U')
cnt2++;
}
return cnt1==cnt2;
}
};
5638.吃苹果的最大数目
优先队列+模拟
用pair< int , int> 来存放苹果的到期时间和现有数量。
用priority_queue来存储,以到期时间递增方式存储。然后从头开始遍历,如果到期时间到了,就pop出去,如果还剩苹果,那就吃掉一个,如果有剩余则减一后再放入队列,否则就pop出去。
整个结束后返回吃掉的苹果。
class Solution {
public:
int eatenApples(vector<int>& apples, vector<int>& days) {
int res=0;
priority_queue<pair<int,int>,vector<pair<int,int>>,
greater<pair<int,int>>> save; //存放pair
for(int i=0;i<apples.size() || !save.empty();i++) //如果大于n还是可以有苹果,那么继续吃
{
while(!save.empty() && save.top().first==i) //到期了就pop出
save.pop();
if(i<apples.size() && apples[i]!=0) //如果今天产出苹果则加入队列
save.push(make_pair(i+days[i], apples[i]));
if(!save.empty())
{
auto tmp = save.top();
save.pop(); //优先队列不能直接修改,必须pop出修改完后再放入
tmp.second--;
res++;
if(tmp.second>0){ //果子没吃完,放回去
save.push(tmp);
}
}
}
return res;
}
};
5210.球会落何处
DFS
无非就是两种情况:
一、当grid(i,j)=1;
当前板子为 \ ,那么下一列的板子的朝向决定了小球能否下落一行
1.如果j+1<m && grid(i,j+1) = 1 , 则说明当前不是最后一列,而且下一列是 \ ,则说明小球可以下落,且过程是 从 (i ,j)到(i+1,j+1),返回dfs(i+1,j+1)
2.否则,小球则被挡住去路,即 \ | 和 \ / ,返回-1
二、当grid(i,j)=-1;
当前板子为 / ,那么前一列的板子的朝向决定了小球能否下落一行
1.若j>0 &&grid(i,j-1)==-1 ,说明当前不是第一列(| /),或者前一列是-1(/ /), 那么小球就可以下落,过程是从(i,j)到(i+1,j-1),返回dfs(i+1,j-1)
2.否则小球再次就被挡住,即 | /和 \ /,返回-1
那么dfs递归退出条件就是当i==n时,说明小球到达了最底层,返回其j即可
class Solution {
vector<int> ans;
int n, m;
int dfs(vector<vector<int>>& grid, int i, int j) {
if(i==n) return j;
if(grid[i][j]==1 && j+1<m && grid[i][j+1] == 1)
return dfs(grid,i+1,j+1);
else if(grid[i][j]==-1 && j>0 && grid[i][j-1]==-1)
return dfs(grid,i+1,j-1);
return -1;
}
public:
vector<int> findBall(vector<vector<int>>& grid) {
n=grid.size(), m=grid[0].size(), ans.resize(m);
for(int i=0;i<m;i++)
{
ans[i]=dfs(grid,0,i);
}
return ans;
}
};
5640.与数组中元素的最大异或值
此题比赛时写了个离线算法,没有想到用字典树优化(实际上是不熟),在第六十个点左右数据卡超时,其实当时也知道会超时,数量到达了1e5,算法是时间复杂度数O(n²),但还是想试试。因为他这个不超过mi的限制也许会碰巧能过。下面贴出没有完全AC的现场写的代码
const int MAXN=1e5+50;
const int MAXM=1e5*30;
struct Trie{
int sum,ch[2];
}trie[MAXM];
int root,numt;
int init()
{
int x=++numt;
trie[x].ch[0] = trie[x].ch[1]=-1;
trie[x].sum=0;
return x;
}
void insert(int v)
{
int x=root;
trie[x].sum+=1;
for(int i=29;i>=0;i--){
int cur=(v>>i)&1;
if(trie[x].ch[cur]==-1) trie[x].ch[cur]=init();
x=trie[x].ch[cur];
trie[x].sum+=1;
}
}
int query(int v)
{
int x=root,ans=0;
for(int i=29;i>=0;i--){
int cur = ((v>>i)&1)^1;
if(trie[x].ch[cur]!=-1 && trie[trie[x].ch[cur]].sum>0){
ans+=1<<i;
x=trie[x].ch[cur];
}
else if(trie[x].ch[cur^1]!=-1 && trie[trie[x].ch[cur ^ 1]].sum>0){
x=trie[x].ch[cur^1];
}else return -1;
}
return ans;
}
struct Query{
int x,m,i;
}Q[MAXN];
bool cmp(Query& a, Query& b){return a.m < b.m;}
int ans[MAXN];
class Solution{
public:
vector<int>maximizeXor(vector<int>&nums,vector<vector<int>>& queries){
int n=nums.size(),i=0,m=queries.size();
numt=0;
root=init();
sort(nums.begin(),nums.end());
for(int i=0;i<m;i++){
Q[i].i=i;
Q[i].x = queries[i][0];
Q[i].m = queries[i][1];
}
sort(Q,Q+m,cmp);
for(int k=0;k<m;k++){
while(i<n && nums[i]<=Q[k].m) insert(nums[i++]);
ans[Q[k].i] = query(Q[k].x);
}
vector<int>res;
for(int i=0;i<m;i++){
res.push_back(ans[i]);
}
return res;
}
};
正确的写法就不写了,先把字典树研究明白着吧。
好像前缀树也可以做。
附上大佬的链接:https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/0-1zi-dian-shu-by-lucifer1004-4c3e/