Given two positive integers n and k, the binary string Sn is formed as follows:
S1 = "0"Si = Si - 1 + "1" + reverse(invert(Si - 1)) for i > 1Where + denotes the concatenation operation, reverse(x) returns the reversed string x, and invert(x) inverts all the bits in x (0 changes to 1 and 1 changes to 0).
For example, the first four strings in the above sequence are:
S1 = "0"S2 = "011"S3 = "0111001"S4 = "011100110110001"Return the kth bit in Sn. It is guaranteed that k is valid for the given n.
Example 1:
Input: n = 3, k = 1 Output: "0" Explanation: S3 is "0111001". The 1st bit is "0".
Example 2:
Input: n = 4, k = 11 Output: "1" Explanation: S4 is "011100110110001". The 11th bit is "1".
Constraints:
1 <= n <= 201 <= k <= 2n - 1When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method involves generating each binary string one by one until we reach the Nth string. Once we have the Nth binary string, we simply find the Kth bit in that string. This means we build everything out step-by-step until we have our answer.
Here's how the algorithm would work step-by-step:
def find_kth_bit_in_nth_binary_string_brute_force(n, k):
current_string = "0"
for i in range(1, n):
# Build up the binary strings iteratively until we reach the nth string.
inverted_string = ''.join(['1' if bit == '0' else '0' for bit in current_string])
reversed_inverted_string = inverted_string[::-1]
current_string = current_string + "1" + reversed_inverted_string
# After reaching nth string, break since no more computation is required.
# After generating the nth binary string, retrieve the kth bit.
return current_string[k - 1]Instead of generating all the binary strings up to the Nth one, which would take a very long time, we can cleverly figure out the Kth bit by working backwards. We use the properties of how the binary strings are built to efficiently determine the bit without ever constructing the strings themselves.
Here's how the algorithm would work step-by-step:
def find_kth_bit_in_nth_binary_string(nth_string, kth_bit):
inverted = False
while nth_string > 1:
length_of_previous_string = (1 << nth_string) - 1
# If kth_bit is the last bit, we know its value
if kth_bit == (length_of_previous_string + 1) // 2:
return int(inverted)
# If kth_bit is in the second half, it was generated
if kth_bit > (length_of_previous_string + 1) // 2:
kth_bit = length_of_previous_string - kth_bit + 1
inverted = not inverted
nth_string -= 1
# Return the value after potential inversions.
return int(not inverted)| Case | How to Handle |
|---|---|
| n = 0 or k <= 0 | Return an error or throw an exception as the binary string sequence starts from n=1 and k must be positive. |
| n = very large number causing stack overflow with recursive calls | Iterative approach can be used or recursion with memoization to handle large n values to prevent exceeding call stack limit. |
| k exceeds the length of the string generated for nth binary string | Return an error or throw an exception as k cannot be greater than the string length. |
| n = 1, k = 1 | Should return '0' as per the base case S1 = '0'. |
| n is reasonably large (e.g., 20), k is close to the string's maximum length | The algorithm should calculate efficiently and not timeout, testing time complexity is important. |
| k is 1 and n is large | The first bit can be calculated relatively fast as it depends on recursive calls with smaller n. |
| Integer overflow during length calculation of the nth string | Use appropriate data types (long) to prevent integer overflow when computing length of string. |
| If the resulting bit is not '0' or '1' | Return an error or throw an exception indicating the produced result is invalid, which would happen with a bug in the algorithm. |