LeetCode第337场周赛

本文介绍了LeetCode第337场周赛的四道编程题目,包括奇偶位数的位操作解法,检查骑士能否按序遍历棋盘的逻辑判断,计算美丽子集的动态规划策略,以及寻找执行操作后最大MEX的算法。每道题都提供了思路和代码实现。
摘要由CSDN通过智能技术生成

2023.3.19LeetCode第337场周赛

A. 奇偶位数

思路

枚举每一位是否为1

代码

class Solution {
public:
    vector<int> evenOddBit(int n) {
        vector<int> ans(2);
        int f = 0;
        while (n) {
            if (n & 1) {
                ans[f] ++ ;                    
            }
            f ^= 1;
            n >>= 1;
        }
        return ans;
    }
};

B. 检查骑士巡视方案

思路

将每个点的序号记录下来,按顺序检查相邻点之间是否可以到达

代码

typedef pair<int, int> PII;
#define x first
#define y second

class Solution {
public:
    bool checkValidGrid(vector<vector<int>>& grid) {
        vector<PII> a;
        int n = grid.size();
        a.resize(n * n);
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < n; j ++ )
                a[grid[i][j]] = {i, j};
        if (!(a[0].x == 0 && a[0].y == 0)) return false;
        for (int i = 1; i < n * n; i ++ ) {
            int x1 = a[i].x, y1 = a[i].y, x2 = a[i - 1].x, y2 = a[i - 1].y;
            if (abs(x1 - x2) == 1 && abs(y1 - y2) == 2 || abs(x1 - x2) == 2 && abs(y1 - y2) == 1) continue;
            return false;
        }
        return true;
    }
};

C. 美丽子集的数目

思路

将所有数按照对k的余数相同的进行分组,只有同余的数才有可能互斥
先求出每一组中的美丽子集的数量,使用乘法原理相乘得到最后答案
求每一组中的数量可以使用动态规划,选和不选当前数
如果不选从前一个转移而来,如果选则要判断是否互斥,且要去除空集

代码

class Solution {
public:
    int beautifulSubsets(vector<int>& nums, int k) {
        unordered_map<int, map<int, int>> group; //分成同余的组
        for (auto x : nums)
            group[x % k][x] ++ ;
        int ans = 1;
        for (auto [_, g] : group) {
            int n = g.size();
            vector<int> f(n + 1);
            auto it = g.begin();
            f[0] = 1;
            f[1] = (1 << it->second);
            int la = it->first;
            it ++ ;
            for (int i = 2; i <= n; it ++ , i ++ ) {
                f[i] = f[i - 1]; //不选当前数
                if (it->first - la == k) //选当前数
                    f[i] += f[i - 2] * ((1 << it->second) - 1);
                else 
                    f[i] += f[i - 1] * ((1 << it->second) - 1);
                la = it->first;
            }
            ans *= f[n]; //每个组的数量
        }
        return ans - 1; //减去空集
    }
};

D. 执行操作后的最大 MEX

思路

负数x对m取余 (x % m + m) % m
记录所有元素的余数,从小到大枚举mex,直到数量不足就是答案

代码

class Solution {
public:
    int findSmallestInteger(vector<int>& nums, int m) {
        vector<int> cnt(m);
        for (auto x : nums)
            cnt[(x % m + m) % m] ++ ;
        int ans = 0;
        while (cnt[ans % m] -- ) {
            ans ++ ;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值