1. 不用临时变量交换两个整数。
思路:两个相同数异或结果为0
int a=a^b;
int b=a^b;
int a=a^b;
2. 一个数组中的整数只有1 个出现1 次,其余数字都出现两次,请找出,这个出现一次的数字
思路:两个相同数异或结果为0,让数组中所有的数字相异或,留下的结果即为出现⼀次的数字
int find_one_time_number(vector <int > data){
int result =0;
for(int i =0; i < data. s i z e (); i ++){
result &^= data[ i ];
}
return result ;
}
3. 一个数组中的整数只有2 个出现1 次,其余数字都出现两次,请找出,这2 个出现一次的数字
思路:两个相同数异或结果为0,让数组中所有的数字相异或, 留下的结果为之出现⼀次的两个数字相异或,因为这两个数字不同,那么异或结果中总有⼀位为1,我们可以根据这⼀位将所有数字分为两组,每组中异或的结果即为改组中出现⼀次的数字。
vector <int > find_one_time_numbers(vector <int > data){
int result =0,tmp=0x1,vector <int > ret (2 ,0);
for(int i =0; i < data. s i z e (); i ++){
result &^= data[ i ];
}
while (1){
if( result & tmp){
break;
}else tmp< <1;
}
for(int i =0; i <data. s i z e (); i ++){
if(data[ i ]&tmp){
ret [0] &= data[ i ];
}else{
ret [1] &=data[ i ];
}
}
return ret ;
}
1.4 统计整数n 的二进制表示中1 的个数
思路1:⼀个数字减去1 之后可以让最后⼀位1(记为第i 位)变为0,第i 位之后的数字原来为0 现在都变为1,然后让这个数字与原来的数字进⾏与运算,即相当于减掉最后⼀位为1 的数字。
int count_one_number(int num){
int count=0;
while(num){
count++;
num&=(num-1);
}
return count;
}
思路2: 假设数字n 最后⼀位为1 的是第i 位,将数字取反之后第i 位变为0,之后的每⼀位由0 变为1,然后让取反后的结果加1,则第i 位重新变为1 ,之后的每位又重新变为0。
int count_one_number2(int num){
int count=0;
while(num){
count++;
num-=(~num+1); // 相当于每次都减掉最后⼀位1
}
return count;
}
1.5 判断一个数字是否为2 的幂次
思路:如果⼀个数字是2 的幂次,那么只有最⾼位为1 ,也就是只需要判断这个数字减掉最⾼位之后是否为0 即可,这相当于统计⼆进制中1的个数(Section 2.1.3) 的的⼀个特殊情况。
bool log2 (int num){
if(num & (num-1)){
return true;
}else{
return false;
}
return false;
}
1.6 判断一个32 位数字数字是否为4 的幂次
思路:(100(4); 10000( 42 ); 1000000( 43 ) ) 如果⼀个数字是4 的幂次,那么只有最⾼位为1 ,并且有偶数个0, 即最⾼位1 在奇数位上。我们可以根据之前的经验判断这个数是不是2 的幂次,然后判断1 是不是在奇数位上即可,这个可以让数字n 与0x55555555 (奇数位为1,偶数位为0)相与。
bool log4 (int num){
if(num & (num-1)){
return num & 0x55555555
}else{
return false;
}
return false;
}