题目1:下一个数
给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。
示例:
输入:num = 2(或者0b10)
输出:[4, 1] 或者([0b100, 0b1])
输入:num = 1
输出:[2, -1]
解题思路:
1.先用bitset将num的32位二进制表示出来,存放到数组中,方便可以遍历
2.较大值:从左往右找到第一个01,将其转换成10,再将右侧剩余的1全都移动到最低位
eg.0101110 ->1000111
3.较小值:从左往右找到第一个10,将其转换成01, 再将右侧剩余的1全都移动到最高位
eg.1001110 ->0111100
4.bitset数组的下标是从低位开始的,也就是从右往左进行遍历
源代码如下:
class Solution {
public:
vector<int> findClosedNumbers(int num) {
bitset<32> smaller(num);//将二进制表示出来
bitset<32> bigger(num);
//找较小值
int a=-1;//a初始化为-1
for(int i=1;i<32;i++)
{
//找到10,变成01
if(smaller[i]==1 && smaller[i-1]==0)
{
smaller.flip(i);//flip(i)将第i位上的数字进行翻转 (0转1,1转0)
smaller.flip(i-1);
//将右侧剩余的1,全移动到高位
//相当于left和right的位互换
for(int left=0,right=i-2;left<right;)
{
//从低位找到第一个不为0的
while(left<right && smaller[left]==0) left++;
//从高位找到第一个不为1的
while(left<right && smaller[right]==1) right--;
//位翻转
smaller.flip(left);
smaller.flip(right);
}
//smaller.to_ulong() 将数组smaller转成unsigned long类型的值
//再强转成int类型
a=(int)smaller.to_ulong();
break;
}
}
//找较大值
int b=-1;
//在找较大值时,bigger要保证正数,最高符号位保证为0,最大正数为2147483647,2进制31个1,i只能到第30位,如果写 i<32 会出现上溢,所以这里与较小值不同的点在于要将i<32改为i<31,防止溢出
for(int i=1;i<31;i++)
{
//找到01,变成10
if(bigger[i]==0 && bigger[i-1]==1)
{
bigger.flip(i);
bigger.flip(i-1);
//将右侧剩余的1全移动到低位
for(int left=0,right=i-2;left<right;)
{
while(left<right && bigger[left]==1) left++;
while(left<right && bigger[right]==0) right--;
bigger.flip(left);
bigger.flip(right);
}
b=(int)bigger.to_ulong();
break;
}
}
return {b,a};
}
};
题目2:整数转换
编写一个函数,确定需要改变几个位才能将整数A转成整数B。
示例:
输入:A = 29 (或者0b11101), B = 15(或者0b01111)
输出:2
输入:A = 1,B = 2
输出:2
解题思路:
1.用bitset将整数A和B的32位 二进制表示出来存放在数组里,进行遍历
2.遇到aa[i]!=bb[i],说明需要转换,count++即可
源代码如下:
class Solution {
public:
int convertInteger(int A, int B) {
bitset<32> aa(A);//A的二进制
bitset<32> bb(B);//B的二进制
int i=0;//都是32位,所以只需要一个下标进行遍历
int count=0;//用来记录需要改变的次数
while(i<32)
{
//遇到当前位不相等的,就需要转换,count++
if(aa[i]!=bb[i])
{
count++;
}
i++;
}
//返回count
return count;
}
};
题目3:配对交换
编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。
示例:
输入:num = 2(或者0b10)
输出 1 (或者 0b01)
解题思路:
1.用bitset将num的二进制保存到数组中,便于用下标进行访问
2.从低到高两两进行交换,i+=2
3.将最后的结果用to_ulong()函数先转成unsigned long类型,再强转成int类型
源代码如下:
class Solution {
public:
int exchangeBits(int num) {
bitset<32> bit(num);
int i=0;
//从低到高进行两两交换
//注意:因为要访问i+1,所以循环结束条件为i<31,防止越界
while(i<31)
{
int temp=bit[i];
bit[i]=bit[i+1];
bit[i+1]=temp;
i+=2;//i每次跳两个位数
}
//bit.to_ulong() 将二进制数转成unsigned long类型的值
//再强转成int类型,就可以返回了
return (int)bit.to_ulong();
}
};