题目链接
就是寻找一个略大的数字和一个略小的数字
首先说一下如何找略小的数字
分析略小的数字
先举例子
0100 0111 比这个略小的 0011 1100
0010 0000 比这个略小的 0001 0000
…
多分析几个数字,可知,就是找到 10,然后转换成01,并且后边如果有1的话,全都移到最靠近01的右边。
代码实现:
int copy = num;//先复制一份,因为后面需要将这个数字进行移位
//略小 找 10 变 01 并将 1111.。。移近 01
int bitCount = 0;//记录10后面一共有多少位,因为后面在将10变为01的时候需要
//开始寻找 10
//将数字与 3也就是 与 11 可以求出最后两位是 00 或者 01 或者 10 或者 11
while ((copy & 3) != 2){
//如果进来了,说明 copy最后两位不是 10
if(copy == 0){//如果copy等于0了,那么再怎么移位,也不可能移出10了,为了避免死循环,此时应该break
break;
}
copy >>= 1;//左移一位,说明此时还没有找到10
bitCount++;//此时10后面至少有一位
}
//出循环说明,要不就是找到了10 要不就是整个数字的二进制中不存在10
if(copy!=0){// copy不等于0说明找到了10
//将copy左移的总的位数 全部移动回来,但是此时10 后面全是0了,不管原来是多少,此时都是0了
//假设一开始是0100 0111 此时copy=010
//copy = 010 * 2^5 = 0100 0000
copy = (int)(copy * Math.pow(2,bitCount));
//然后我们需要将后面如果有1,则移到最靠近10的位置
//首先,我们分析一下,后面可能的情况
// 简单分析就可知,后面只能是 000000 或者000001111
//就是后面要不就是全是0 要不就是好多0在好多1前面 只有这两种情况
int yu = num - copy;
//然后我们将10变为01 也就是 0100 0000 变为 0010 0000
//只要copy - 2^5 即可
copy = (int)(copy - Math.pow(2,bitCount));// 10变 01
if(yu!=0){
//此时说明是好多0在好多1前面,反之,如果后面全是0,那么就不用处理了,只要10变01就结束了
//接下来就是我们如何确定yu移到了最靠近01的位置
//只需要比较 最靠近01的位置设置为1,只要yu大于等于这个数字了,说明已经到了最靠近的位置了
while (yu < Math.pow(2,bitCount-1)){
yu <<= 1;
}
copy += yu;//此时将后面的数字加上即可
}
}else{//此时说明整个数字中不存在10也就是说,全是1,也就是最大的那个数字
copy = -1;
}
找到略大的也是同样的道理,不同的是,需要找的是01,变为10,并将右边的1,全部移动到最右边
整体代码:
class Solution {
public int[] findClosedNumbers(int num) {
int copy = num;
//略小 找 10 变 01 并将 1111.。。移近 01
int bitCount = 0;
while ((copy & 3) != 2){
if(copy == 0){
break;
}
copy >>= 1;
bitCount++;
}
if(copy!=0){
copy = (int)(copy * Math.pow(2,bitCount));
int yu = num - copy;// yu一定是 000000111111
copy = (int)(copy - Math.pow(2,bitCount));// 10变 01
if(yu!=0){
while (yu < Math.pow(2,bitCount-1)){
yu <<= 1;
}
copy += yu;
}
}else{
copy = -1;
}
//找略大 找01变 10 并将 111移到最右边
int copy2 = num;
bitCount = 0;
while ((copy2 & 3) != 1){
copy2 >>= 1;
bitCount++;
if(bitCount==30){
break;
}
}
if(bitCount == 30){
return new int[]{-1,copy};
}
copy2 = (int)(copy2 * Math.pow(2,bitCount));
int yu = num - copy2;
copy2 = (int)(copy2 + Math.pow(2,bitCount));
if(yu != 0){
while (yu % 2 != 1){
yu >>= 1;
}
copy2 += yu;
}
return new int[]{copy2,copy};
}
}