分为两个步骤
1、对于略小数,要找到最右边的,第一个满足“该位为1且右一位为0”的位数;要让他有空间向右移,从而变小,很好理解
对于略大数,要找到最右边的,第一个满足“该位为1且左一位为0”的位数;类上。
2、可以发现对于 100011 ,其略小数并不是010011而是011100。所以光是移位第一步找到的一是不够的,要把右边所有的的1都往左靠才能得到略小数,同样的往右靠能得到略大数
实现的代码,根据位运算的掌握程度有很多实现方式,下面给出最朴素的实现(能力不够。。)
class Solution {
public int[] findClosedNumbers(int num) {
int[] ans = new int[2];
int m = -1, n = -1;
int[] cunt = new int[32];
for(int i = 0; i < 31; i++){
if(i > 0)
cunt[i] = cunt[i - 1];
int k = num & (1 << i);
if(k > 0){
cunt[i] ++;
int m1 = num & (1 << (i - 1));
int n1 = num & (1 << (i + 1));
if(i > 0 && m1 == 0 && m == -1)
m = i;
if(i < 30 && n1 == 0 && n == -1)
n = i;
}
}
if(m == -1){
ans[1] = -1;
}else{
for(int i = 1; i <= cunt[m]; i++)
ans[1] += (1 << (m - i));
for(int i = m + 1; i < 31; i++){
int k = num & (1 << i);
ans[1] += k;
}
}
if(n == -1){
ans[0] = -1;
}else{
int k = (1 << (n + 1));
ans[0] += k;
for(int i = 0; i < cunt[n] - 1; i++)
ans[0] += (1 << i);
for(int i = n + 2; i < 31; i++){
k = num & (1 << i);
ans[0] += k;
}
}
return ans;
}
}