Here’s another O(1) solution that is an optimization of the original answer:
int closestIntegerWithSameWeight(int x) {
if ((x & 1) == 1) {
// Swap leftmost bit of group of bits on right with the zero to the left
// eg. 0111 -> 1011
int inverse = ~x;
int lsbInverse = inverse & ~(inverse - 1);
x |= lsbInverse;
return x & ~(lsbInverse >> 1);
} else {
// Swap LSB with zero on right
// eg. 1010 -> 1001
int lsb = x & ~(x - 1);
return (x & ~lsb) | (lsb >> 1);
}
}