Problem
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))
fori > 1
Where +
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 = "0**1**1"
S3 = "011**1**001"
S4 = "0111001**1**0110001"
Return the kth
bit in Sn
. It is guaranteed that k
is valid for the given n
.
Examples
Example 1:
Input: n = 3, k = 1
Output: "0"
Explanation: S3 is "**0**111001".
The 1st bit is "0".
Example 2:
Input: n = 4, k = 11
Output: "1"
Explanation: S4 is "0111001101**1**0001".
The 11th bit is "1".
Solution
Method 1 - Using recursion
Given the nature of how the binary strings S_n
are generated recursively, explicitly constructing the strings up to S_n
would be inefficient for larger values of n
.
Each binary string is formed recursively by inserting a “1” in the middle and appending an inverted and reversed version of the previous string. So, by understanding the structure and recursive generation of the strings, we can determine the k-th
bit efficiently using recursion or iteration. The recursive relationship allows us to bypass the need to generate the entire string and directly find the k-th bit by:
- Identifying the midpoint.
- Determining the position of
k
relative to the midpoint. - Using the properties of inversion and reversal.
Approach
Here is the approach:
- Recursive Structure:
- Each string
S_n
is derived from the previous stringS_{n-1}
by appending1
and the reversed inverted version ofS_{n-1}
. - Key observations:
- The midpoint of
S_n
is at index2^(n-1)
. - The structure of each part is symmetric.
- The midpoint of
- Each string
- Base Case:
- If
n = 1
, the string is"0"
.
- If
- Recursion:
- If
k
equals the midpoint, return1
. - If
k
lies in the first half, recursively find the bit inS_{n-1}
. - If
k
lies in the second half, find the corresponding position in the first half ofS_{n-1}
, compute the bit, and then invert it.
- If
Code
Java
class Solution {
public char findKthBit(int n, int k) {
// Base case: When n is 1, S1 is "0"
if (n == 1) {
return '0';
}
// Calculate the length of Sn, which is 2^n - 1
int length = (1 << n) - 1; // Equivalent to Math.pow(2, n) - 1
// Calculate the midpoint position
int mid = (length / 2) + 1;
// If k is the midpoint, the k-th bit is always '1'
if (k == mid) {
return '1';
}
// If k is in the first half, recursively find the bit in Sn-1
else if (k < mid) {
return findKthBit(n - 1, k);
}
// If k is in the second half
else {
// Find the equivalent position in the first half and invert the result
int mirrored_pos = mid - (k - mid);
return findKthBit(n - 1, mirrored_pos) == '0' ? '1' : '0';
}
}
}
Python
class Solution:
def findKthBit(self, n: int, k: int) -> str:
if n == 1:
return '0'
length = 2 ** n - 1
mid = length // 2 + 1
if k == mid:
return '1'
elif k < mid:
return self.findKthBit(n - 1, k)
else:
# Find the equivalent position in the first half and invert
mirrored_pos = mid - (k - mid)
return '1' if self.findKthBit(n - 1, mirrored_pos) == '0' else '0'
Complexity
- ⏰ Time complexity:
O(n)
, because each recursive call reduces the size by half. - 🧺 Space complexity:
O(n)
, due to recursion stack.