五月集训(第10天) —— 位运算
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五月集训(第10天) —— 位运算相关的知识,希望对你有一定的参考价值。
文章目录
前言
此为《英雄算法联盟:算法集训》的内容,具体内容详见:知识星球:英雄算法联盟。加入星球后,即可享用星主 CSDN付费专栏 免费阅读 的权益。
欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
希望大家先自己思考,如果实在没有想法,再看下面的算法思路,如果有思路但是写不出来,可以参考朋友圈中其他人的代码,总有一款是适合你的,关注一下他,取其之长,补给之短。
今天集训的内容是:位运算
前三题较为简单,第四题有一些技巧,想出来以后就会很有成就感,建议想一想。
一、练习题目
题目链接 | 难度 |
---|---|
191. 位1的个数 | ★☆☆☆☆ |
461. 汉明距离 | ★☆☆☆☆ |
136. 只出现一次的数字 | ★☆☆☆☆ |
137. 只出现一次的数字 II | ★★★☆☆ |
二、算法思路
1、位1的个数
(1)把一个数想象成二进制,先判断最低位是多少(可以用 位与),并且累加到结果上;
(2)将这个数右移一位,继续 (1) 的判断,直到这个数为 0 为止。
(3)思考:位与1·相当于 模2;右移一位相当于 除2。
int hammingWeight(uint32_t n)
int ans = 0;
while(n)
ans += (n & 1);
n >>= 1;
return ans;
2、汉明距离
(1)对于两个数来说,如果相同位置的二进制位相同,则对应汉明距离为 0,否则为 1;和异或的性质不谋而合,所以可以将两个数异或以后,求异或结果的 位1的个数。
int hammingWeight(uint32_t n)
// 复用第一题的代码
int hammingDistance(int x, int y)
return hammingWeight(x^y);
3、只出现一次的数字
(1)任意两个数异或的结果为 0,所以只要偶数个数异或,结果都为 0;
(2)异或满足交换律和结合律,所以把所有数异或以后,得到的数就是我们要求的那个只出现一次的数。
int singleNumber(int* nums, int numsSize)
int ans = 0, i;
for(i = 0; i < numsSize; ++i)
ans ^= nums[i];
return ans;
4、只出现一次的数字 II
(1)这题将原本的两个数变成了三个数,于是用异或就行不通了;
(2)将每个数转换成二进制以后排列起来;
(3)对于每个位进行分别计算,如果加起来是3的倍数,说明只出现一次的数的对应位是0;否则,是1;
int singleNumber(int* nums, int n)
int ret = 0;
for(int i = 0; i < 32; ++i)
int ans = 0;
for(int j = 0; j < n; ++j)
ans += (nums[j] >> i) & 1;
ans %= 3;
if(ans)
ret += ((unsigned int)1<<i);
return ret;


以上是关于五月集训(第10天) —— 位运算的主要内容,如果未能解决你的问题,请参考以下文章