LeetCode---382周赛---位运算

题目列表

3019. 按键变更的次数

3020. 子集中元素的最大数量

3021. Alice 和 Bob 玩鲜花游戏

3022. 给定操作次数内使剩余元素的或值最小

一、按键变更的次数

LeetCode---382周赛---位运算_第1张图片 题目简单明了,就是看相邻的两个字母是否相等,不区分大小写,直接遍历统计即可,这里讲一个位运算的小技巧

LeetCode---382周赛---位运算_第2张图片

代码如下

class Solution {
public:
    int countKeyChanges(string s) {
        int ans=0;
        for(int i=1;i

二、子集中元素的最大数量

LeetCode---382周赛---位运算_第3张图片

这题不是很难,只要暴力枚举出所有子集的长度,取最大长度就行。但是这题的坑比较多,要注意很多细节,具体看代码

class Solution {
public:
    int maximumLength(vector& nums) {
        unordered_mapcnt;
        for(auto x:nums) cnt[x]++;//统计数字出现的次数
        int ans=1;
        for(auto [x,y]:cnt){//枚举哈希表,即枚举每个数为子集的第一个数的情况
            if(x==1) ans=max(ans,y-(y%2==0));//如果第一个数为1,需要特判
            else{
                int tmp=x,k=0;
                while(cnt.count(tmp)){
                    k+=2;
                    //注意超int范围和数只出现一次的情况
                    if(cnt[tmp]==1||1LL*tmp*tmp>INT_MAX){
                        k--;
                        break;
                    }
                    tmp*=tmp;
                }
                if(k%2==0) k--;//注意tmp不存在的情况
                ans=max(ans,k);
            }
        }
        return ans;
    }
};

三、Alice和Bob玩鲜花游戏

LeetCode---382周赛---位运算_第4张图片这题就是阅读理解找规律,我们先来只考虑两人拿一条边上的鲜花的情况,如果是奇数,Alice必赢,如果是偶数,Alice必输,现在我们来想想,两条边呢,为了保证Alice必赢,我们只要保证一条边的鲜花为偶数,另外一条边的鲜花为奇数即可,为什么?

因为Alice只要从奇数中拿掉一个,剩下的两条边上鲜花的个数都是偶数,无论Bob如何选择,都无法获胜,那么胜者只能是Alice。其他的情况,只要Alice拿掉一朵鲜花,Bob面对的情况就和刚刚说的一样,即Bob必胜

代码如下

class Solution {
public:
    long long flowerGame(int n, int m) {
        long long l=(n+1)/2,r=(m+1)/2;//求出左边的数的奇数个数和右边数的奇数个数
        return r*(n-l)+l*(m-r);//奇偶配对
    }
};

四、给定操作次数内使剩余元素的或值最小

LeetCode---382周赛---位运算_第5张图片

又是一个位运算的题目,像这类的题目一般可以用拆位的方法来做,即一个个比特位的考虑。这题也是同理,我们可以从高位开始枚举一直枚举到低位,看看答案每个比特位是否能取到1。本质是在构造一个符合条件的最小值。

先来简单解释一下为什么是从高位向低位枚举,而不是从低位向高位枚举。这个可以看作是贪心的策略,本质是比特位的权重不同,举个例子 (1<<4) > (1<<4)-1 ,从二进制的角度看,第四位上的1,比后三位上的1 加起来还大。具体证明就不说了,如果想不明白,可以结合示例多想想。

如何判断比特位上的1能否去掉呢?

LeetCode---382周赛---位运算_第6张图片

class Solution {
public:
    int minOrAfterOperations(vector& nums, int k) {
        int ans=0,mask=0;
        for(int i=31;i>=0;i--){
            mask|=(1<k,题目数据范围限定了n>k,n=nums.size()
            if(cnt>k){
                ans|=(1<

你可能感兴趣的:(leetcode,算法,职场和发展)