LeetCode第264场周赛解题记录

在这里插入图片描述

T1 1903. 字符串中的最大奇数

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    string largestOddNumber(string num) {
        string res;
        for(int i = num.size(); i >= 0; i--)
        {
            int x = num[i] - '0';
            if(x % 2 == 0)continue;
            for(int j = 0; j <= i; j++)
                res += num[j];
            break;
        }
        return res;
    }
};



T2 1904. 你完成的完整对局数

在这里插入图片描述
在这里插入图片描述

思路:

  1. 将字符串转化为数字,将单位统一成分钟。
  2. 计算对局次数:(代码实现将两种情况(能否整除15)统一
    1. 若没有熬夜:
      1. 若开始时间为15的整数倍,则开始时间不变,否则:
        start = start+15 - (start + 15) % 15。
      2. 若结束时间为15的整数倍,则结束时间不变,否则:
        finish = finish - (finish % 15)。
      3. 参与对局次数:(finish - start) / 15
    2. 若熬夜了,则计算一天的总对局次数减去没有参与的对局次数。
      1. 若开始时间为15的整数倍,则开始时间不变,否则:
        start = start - (start % 15)
      2. 若结束时间为15的倍数,则结束时间不变,否则:
        finish = finish + 15 - (finish + 15) % 15
      3. 没参与的对局次数:(finish - start) / 15
      4. 参与的对局次数:24 * 4 - 没参与的对局次数
class Solution {
public:
    int numberOfRounds(string startTime, string finishTime) {
        int startT = ((startTime[0] - '0') * 10 + startTime[1] - '0') * 60 + (startTime[3] - '0') * 10 + startTime[4] - '0';
        int finishT = ((finishTime[0] - '0') * 10 + finishTime[1] - '0') * 60 + (finishTime[3] - '0') * 10 + finishTime[4] - '0';
        int res = 0;
        if(startT > finishT)
            res = 24 * 4 - ( startT + 14 - (startT + 14) % 15 - (finishT - finishT % 15)) / 15;
        else
            res = (finishT - finishT % 15 - (startT + 14 - (startT + 14) % 15) ) / 15;
        return res;
    }
};



T3 1905. 统计子岛屿

在这里插入图片描述
在这里插入图片描述

思路:dfs+标记 o(n2)

  1. 从公共部分并且没搜过的格子开始搜,只要该格子被搜过,无论其所在的岛屿是否为子岛屿都不必重新再搜一遍。(若为子岛屿,则无需也不应该重复计数,若不为则不用搜)
  2. 每搜一个格子就对其标记,用一个bool数组存储grid2格子是否被标记,grid1尽量避免修改。
class Solution {
public:
    vector<vector<int>>g1, g2;
    int n, m;
    bool flag;
    vector<vector<bool>>st;
    int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
    void dfs(int x, int y)
    {
        for(int i = 0; i < 4; i++)
        {
            int a = x + dx[i], b = y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= m)continue;
            if(st[a][b] || g2[a][b] == 0)continue;
            st[a][b] = true;
            if(g1[a][b] == 0)flag = false;
            dfs(a, b);
        }
        
    }
    int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
        g1 = grid1, g2 = grid2;
        n = g1.size(), m = g1[0].size();
        st = vector<vector<bool>>(n, vector<bool>(m, false));
        int res = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                flag = true;
                if(g1[i][j] == 1 && g2[i][j] == 1 && st[i][j] == false)
                    dfs(i, j);
                else continue;
                if(flag)res++;
            }
        return res;
    }
};



4 1906. 查询差绝对值的最小值

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

突破点:nums[i]取值[1,100]
思路:前缀和 o(100n)

  1. 前缀和:统计出整数数组任意前缀1-100的出现次数。
  2. 查询时通过前缀和数组运算可快速得出查询区间内1-100出现的次数,将其存入数组cnt[]中,遍历一遍该数组统计出两个非0元素的最短下标距离为本次查询结果。
class Solution {
public:
    vector<int> minDifference(vector<int>& nums, vector<vector<int>>& queries) {
        int s[110000][110] = {0};
        int n = nums.size(), m = queries.size();
        for(int i = 0; i < n; i++)
            for(int j = 1; j <= 100; j++)
            {
                s[i + 1][j] = s[i][j];
                if(j == nums[i])
                    s[i + 1][j]++;
            }
            
        vector<int>res;
        for(int i = 0; i < m; i++)
        {
            int l = queries[i][0], r = queries[i][1];
            l++, r++;
            int cnt[110];
            for(int j = 1; j <= 100; j++)
                cnt[j] = s[r][j] - s[l - 1][j];
            int last = -1, t = INT_MAX;
            for(int j = 1; j <= 100; j++)
            {
                if(cnt[j])
                {
                    if(last == -1)
                        last = j;
                    else
                    {
                        t = min(t, j - last);
                        last = j;
                    }
                }
            }
            if(t == INT_MAX)t = -1;
            res.push_back(t);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值