力扣集训第10天

差了4天会补上的

面试题 16.01 交换数字

解题思路

我们只需要知道最基本的公式就是,当两个相同的数进行异或时,结果为0,即a^a为0,a = a^b如果想得到a为b只需要在此基础上再异或一个a即可。

代码

class Solution {
public:
    vector<int> swapNumbers(vector<int>& numbers) {
        numbers[0] ^= numbers[1];//a^b
        numbers[1] ^= numbers[0];//b = a ^ b ^ b->b = a
        numbers[0] ^= numbers[1];//a = a ^ b ^ a->a = b
        return numbers;
    }
};

1342 将数字变成0的操作次数

解题思路

按步骤计算即可。可参考注释
要注意奇数和偶数的位运算判断。

代码

class Solution {
public:
    int numberOfSteps(int num) {
        int ret = 0;
        while (num) {
            //当num为1时,既是奇数但减一后为0,只有 1步,所以要单独讨论。
            ret += (num > 1 ? 1 : 0) + (num & 0x01);//如果是奇数,那么减一算一步,除以二再算一步。
            num >>= 1;
        }
        return ret;
    }
};

476 数字的补数

解题思路

我们需要注意二进制最高位0表示正,1表示负数。
对于此题,我们只要知道这个数的二进制位数即可通过与相同位数的二进制位全1整数进行异或即可。

代码

class Solution {
public:
    int findComplement(int num) {
        //想要知道这个数在二进制中是多少位的。
        int highbit = 0;
        for(int i = 1;i<= 30;i++){
            if(num >= (1 << i)){
                highbit = i;
            }
            else {
                break;
            }
        }
        //注意当highbit等于30时,即将(hightbit+1->31)1左移31位,共32位,值为2**31,再减一就是int在正数部分的最大值。但这样会让符号位为1导致变负数,所以得单独讨论,用首位为0其余为1.和num进行异或.
        int mask = (highbit == 30?0x7FFFFFFF:(1 << (highbit + 1)) - 1);
        return num ^ mask;
    }
};

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

解题思路

二进制i中存储这对n个数的选取情况,选完之后还要再循环找回去第几个数被选中,即nums[j]被选中。

代码

class Solution {
public:
    int countMaxOrSubsets(vector<int>& nums) {
        /*
            1.最多有2**nums.size()-1个非空子集。
            2.或:都为0时才为0其余为1.
        */
        int n = nums.size(), maxValue = 0, cnt = 0, stateNumber = 1 << n;
        for(int i = 0;i<nums.size();i++)
            maxValue |= nums[i];
        for (int i = 0; i < stateNumber; i++) {
            int cur = 0;//因为stateNumber-1为选中集合中所有元素所以cur就不用赋为0了。
            for (int j = 0; j < n; j++) {
                if (((i >> j) & 1) == 1) {
                    cur |= nums[j];
                }
            }
            if(cur == maxValue){
                cnt++;
            }
            // if (cur == maxValue) {
            //     cnt++;
            // } else if (cur > maxValue) {//不断让maxValue变大,最终整个集合的或是最大的。或起来只会大于等于原来两个数,不会变小。找到后cnt为1即可。
            //     maxValue = cur;
            //     cnt = 1;
            // }
        }
        return cnt;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值