First of all, note that the 0-bits in x denote the bits that should be 0 in k, while the 1-bit in x can be either 0 or 1 in k. Thus, the algorithm should iterate over all possible bit combinations in k, where x has 1 bit, and the resulting number (k) is not more than n.
These combinations are best created using something like Gray code , because then you can move from one bit pattern to the next in constant time.
Example:
x = 0b011010 (26) n = 0b010000 (16)
The values โโgenerated for k (in the order of the sulfur code sequence):
0b000000 ( = 0) 0b000010 ( = 2) 0b001010 ( = 10) 0b001000 ( = 8) 0b011000 ( = 24) too large: exclude 0b011010 ( = 26) too large: exclude 0b010010 ( = 18) too large: exclude 0b010000 ( = 16)
Due to the use of the Gray code scheme, only one bit changes from one combination to the next. This means that numbers are not generated in order, and some may be too large (> n). This drawback is worth whatever it does, since generating them in order would require more bit-by-bit changes.
Here is a snippet that implements this idea in JavaScript:
function get_nums(n, x) {
Note that the output is not ordered (due to the Gray code sequence used). If you need to order them, apply some sort of radix sorting (or hashing).
JavaScript is pretty simple to implement such a radix sort, given that the values โโare unique. But in other languages, you could implement a more explicit, simplified radix sort . Here is the JavaScript function for it:
function radix_sort_uniques(arr) { let result = {};
Complexity:
The outer loop is repeated once per position bit in n, i.e. log (n) times, while the inner loop approximately doubles each time with its number of iterations. Therefore, in the worst case (when x is 0, and the inner loop is always executed), we get the total number of innermost operations in the order of 2 log (n) times, giving time O (n) complexity.
Since x is fixed, complexity must also be expressed in x. Let them say that x has b 1 bits, then the time complexity is O (b + 2 b ).