力扣 第263场周赛 总结

检查句子中的数字是否递增

题目描述:力扣 5902.检查句子中的数字是否递增

解题思路:

遍历一遍字符串,p代表前值,n代表后值,随着遍历,p和n不断变化;并判断:

当n<=p时,false

代码

class Solution 
{
public:
    bool areNumbersAscending(string s) {
        int i;
        int p=0;
		int n=0;
        for(i=0;i<s.length();i++)
        {
            if(s[i]>='0'&&s[i]<='9')
            {
                int num=s[i]-'0';
                n=n*10+num;
            }
            else
            {
                if(n){
                    if(n<=p)  
                        return false;
                    p=n;
                }  
                n=0;
            }
        }
        if(n!=0&&n<=p)
            return false;
        return true;
    }
};

简易银行系统

题目描述:力扣 2043 简易银行系统

代码

class Bank 
{
public:
    vector<long long> nums;
    int n;

    Bank(vector<long long>& balance) 
    {
        this->nums = balance;
        this->n = (int)balance.size();
    }

    bool withdraw(int account, long long money)         //取款
    {
        int x = account - 1;
        if (0 <= x && x < n && nums[x] >= money)
        {
            nums[x] -= money;
            return true;
        }
        return false;
    }

    bool transfer(int account1, int account2, long long money)          //转账,account1取钱,account2存钱
    {
        int x = account1 - 1;
        int y = account2 - 1;
        if (0 <= x && x < n && 0 <= y && y < n && nums[x] >= money)
        {
            nums[x] -= money;
            nums[y] += money;
            return true;
        }
        return false;
    }
    
    bool deposit(int account, long long money)                  //存款
    {
        int x = account - 1;
        if (0 <= x && x < n)
        {
            nums[x] += money;
            return true;
        }
        return false;
    } 
};

统计按位或能得到最大值的子集数目

题目描述:力扣 2044 统计按位或能得到最大值的子集数目

代码

class Solution {
public:
    int ans = 0;
    int countMaxOrSubsets(vector<int>& nums) {
                                            // 按位或是不减的操作,所以全部 | 起来是最大值
        int max = 0;
        for(auto p : nums){
            max |= p;                        //循环按位异或求nums最大值
        }

        dfs(nums, max, 0, 0);
        return ans;
    }
    void dfs(vector<int>& nums, int& m, int idx, int cur){      //cur是子集按位异或的最大值
                                                                // 剪枝
        if(cur == m){
            ans += 1 << (nums.size() - idx);                    //ans是子集个数
            return;
        }

        if(idx == nums.size()){                                //idex是下标
            return;
        }

        dfs(nums, m, idx + 1, cur | nums[idx]);           //加这个数

        dfs(nums, m, idx + 1, cur);                      // 不加这个数
    }
};

到达目的地的第二短时间

题目描述:力扣 2045 到达目的地的第二短时间

解题思路

由于每个点可以重复到达,因此深度优先搜索肯定是用不了的,要使用广度优先搜索(数据结构:队列)
每次搜索时,先检查能否从当前点出发,如果不能(红灯),则修改时间为绿灯亮时


对于每一个当前点的邻接点,加上走边的时间,并入队列。如果当前点是n,则判断是不是第一次达到。如果是,记录下来,如果不是,则看这次的时间有没有比上一次慢,如果相等则还要继续搜索。

由于如果对遇到的每一个节点都入队列,会造成超时,因此这里我们使用剪枝的方法。首先,判断是不是第一次到达这一个点,如果是的话就记录下来并入队列,继续搜索。如果不是,则看是不是第二次到达,并且这次时间要慢于最快到达的时间,如果满足则入队列,继续搜索。显然,最终的结果下所走过的路径一定是第二次所记录到的路径。

代码

class Solution {
public:
    int secondMinimum(int n, vector<vector<int>>& edges, int time, int change) {
        unordered_map<int, vector<int>> e;//邻接表
        for(int i = 0; i < edges.size(); ++i){
            if(e.find(edges[i][0]) == e.end()){
                e[edges[i][0]] = vector<int>();
            }
            if(e.find(edges[i][1]) == e.end()){
                e[edges[i][1]] = vector<int>();
            }
            e[edges[i][0]].push_back(edges[i][1]);
            e[edges[i][1]].push_back(edges[i][0]);
        }
        
        deque<pair<int, int>> q;
        q.push_back(pair<int, int>(1, 0));

        unordered_map<int, int> fir;
        unordered_map<int, int> sec;
        
        int min_time = -1;
        while(q.size() > 0){
            int num = q.size();
            for(int j = 0; j < num; ++j){
                int cur = q.front().first;
                int now = q.front().second;
                q.pop_front();
                if((now / change) % 2 == 1){
                    now = now - (now % change) + change; 
                }
                
                for(auto i: e[cur]){
                    if(i == n){
                        if(min_time != -1 && min_time != (now + time)){
                            return now + time;
                        }
                        min_time = now + time;
                    }
                    if(fir.find(i) == fir.end()){ //看看是不是第一次到达改点,如果是的话记录到达改点最快的时间,并入队列
                        fir[i] = now + time;
                        q.push_back(pair<int, int>(i, now + time));
                        continue;
                    }
                    if(sec.find(i) == sec.end() && fir[i] < now + time){  //看看是不是第二次到达改点,并且第二次的时间比第一次长(而不是等于),如果满足则记录第二快时间,并入队列
                        sec[i] = now + time;
                        q.push_back(pair<int, int>(i, now + time));
                    }
                    
                }
            }
        }
        return 0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值