《七月集训》第十天——位运算

前言

这是七月集训的第十日,今日的训练内容是 位运算

解题报告

第九日的内容比较难,想多做几天,先做一下比较简单的第十日。

1.力扣面试题 16.01. 交换数字

原题链接

面试题 16.01. 交换数字

题目概述

编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。

解题思路

经典的互换方式,只要把代码拆开来写一下就可以看出来是怎么回事。

源码剖析

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* swapNumbers(int* numbers, int numbersSize, int* returnSize){
    int i;
    for(i=1;i<numbersSize;++i){
        numbers[i]=numbers[i]^numbers[i-1];
        numbers[i-1]=numbers[i]^numbers[i-1];
        numbers[i]=numbers[i]^numbers[i-1];
    }
    *returnSize = numbersSize;
    return numbers;
}

2.力扣1342

原题链接

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

题目概述

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

解题思路

按要求解题即可。

源码剖析

int numberOfSteps(int num){
    int ans = 0;
    while(num!=0){
        if(num&1){
            num-=1;
            ans++;
        }else{
            num/=2;
            ans++;
        }
    }
    return ans;
}

3.力扣476

原题链接

476. 数字的补数

题目概述

对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

例如,整数 5 的二进制表示是 “101” ,取反后得到 “010” ,再转回十进制表示得到补数 2 。
给你一个整数 num ,输出它的补数。

解题思路

首先先找到原来的 num 的位数,然后用相同位数的 1 去对原来的数字进行 ^ 操作即可。注意这里的 n 可能会超过最大值,所以只用 int 是不够的。

源码剖析

int findComplement(int num){
    long n = 2;
        while(n - 1 < num){
            n <<= 1;
        }
    return (n - 1) ^ num;
}

4.力扣2044

原题链接

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

题目概述

给你一个整数数组 nums ,请你找出 nums 子集 按位或 可能得到的 最大值 ,并返回按位或能得到最大值的 不同非空子集的数目 。

如果数组 a 可以由数组 b 删除一些元素(或不删除)得到,则认为数组 a 是数组 b 的一个 子集 。如果选中的元素下标位置不一样,则认为两个子集 不同 。

对数组 a 执行 按位或 ,结果等于 a[0] OR a[1] OR … OR a[a.length - 1](下标从 0 开始)。

解题思路

直接暴力枚举,并把符合条件的解记录进计数器,然后就可以得到答案了,这题貌似还可以使用DFS进行解题,先做记录。

源码剖析

int countMaxOrSubsets(int* nums, int numsSize){
    int max = 0;
    int ans = 0;
    for (int i = 1; i < (1 << numsSize); i++) {
        int tmp = 0;
        for (int j = 0; j < numsSize; j++) {
            if (i & (1 << j)) {
                tmp |= nums[j];
            }
        }
        if (tmp == max) {
            ans++;
        } else if (tmp > max) {
            max = tmp;
            ans = 1;
        }
    }
    return ans;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值