位运算-异或运算
题目
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
题解思路
根据位运算中的异或运算,可以知道相同两个数字进行异或运算得到的值是0,一个数与0的异或运算是其本身,所以,将数组中所有数进行异或运算,最终的值就是只出现了一次的元素。
代码
int singleNumber(vector<int>& nums) {
int resp=0;
for(auto e:nums) resp^=e;
return resp;
}
示例
示例 1 :
输入:nums = [2,2,1]
输出:1
示例 2 :
输入:nums = [4,1,2,1,2]
输出:4
位运算-lowbit运算
题目
给定一个长度为n的数列,请你求出数列中每个数的二进制表示中1的个数。输入格式
题解思路
通过lowbit运算求出一个数二进制表示时最小的1的位置,然后用该数减去这个位置上的1,重复这个操作,该数通过了几次操作减为0,该数的二进制中就有几个1;
设定n>0,n的第k位是1,第0~k-1位都是0。
取nn = ~n + 1:
n = 00101100
nn = 11010011 + 1 = 11010100
这样我们可以发现n和nn的最低位的1和后面的0都相同而前面的位都相反,
这时候将n 和 nn进行与运算就可以得到最低位的1和最后的0了,也就是lowbit(n)
即: lowbit(n) = n & (~n + 1)
----------------------------------------------------------------
而我们可以发现: ~n + 1刚好是各位取反末尾加1,也就是补码中的求相反数
即:(~n + 1) = -n
从而可以推导出:lowbit(n) = n & (-n)
代码
#include<iostream>
using namespace std;
int main(){
int n;
scanf("%d",&n);
while(n--){
int x;
scanf("%d",&x);
int res=0;
while(x){
//x&-x,该操作即是求x的最后一位1,,然后用x减去最后一位1,,直至x被减为0;
x-=(x&-x);
res++;
}
cout<<res<<endl;
}
return 0;
}
示例
输入:nums = [1,2,3,4,5]
输出:[1,1,2,1,2]
dl;
}
return 0;
}
#### 示例
输入:nums = [1,2,3,4,5]
输出:[1,1,2,1,2]