LeetCode221周赛

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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值