Skip to content

05.04. Closed Number

Description

Given a positive integer, print the next smallest and the next largest number that have the same number of 1 bits in their binary representation.

Example1:


 Input: num = 2 (0b10)

 Output: [4, 1] ([0b100, 0b1])

Example2:


 Input: num = 1

 Output: [2, -1]

Note:

  1. 1 <= num <= 2147483647
  2. If there is no next smallest or next largest number, output -1.

Solutions

Solution 1: Bit Manipulation

First, let's consider how to find the first number that is larger than $num$ and has the same number of $1$s in its binary representation.

We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $1$ and the adjacent higher bit is $0$, then we have found a position where we can change the $0$ at this position to $1$ and change the $1$ at this position to $0$. Then we move all the remaining lower bits of $1$ to the lowest bit, so we get a number that is larger than $num$ and has the same number of $1$s in its binary representation.

Similarly, we can find the first number that is smaller than $num$ and has the same number of $1$s in its binary representation.

We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $0$ and the adjacent higher bit is $1$, then we have found a position where we can change the $1$ at this position to $0$ and change the $0$ at this position to $1$. Then we move all the remaining lower bits of $0$ to the lowest bit, so we get a number that is smaller than $num$ and has the same number of $1$s in its binary representation.

In implementation, we can use a piece of code to handle the above two situations uniformly.

The time complexity is $O(\log n)$, where $n$ is the size of $num$. The space complexity is $O(1)$.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
    def findClosedNumbers(self, num: int) -> List[int