779. K-th Symbol in Grammar
Description
We build a table of n
rows (1-indexed). We start by writing 0
in the 1st
row. Now in every subsequent row, we look at the previous row and replace each occurrence of 0
with 01
, and each occurrence of 1
with 10
.
- For example, for
n = 3
, the1st
row is0
, the2nd
row is01
, and the3rd
row is0110
.
Given two integer n
and k
, return the kth
(1-indexed) symbol in the nth
row of a table of n
rows.
Example 1:
Input: n = 1, k = 1 Output: 0 Explanation: row 1: 0
Example 2:
Input: n = 2, k = 1 Output: 0 Explanation: row 1: 0 row 2: 01
Example 3:
Input: n = 2, k = 2 Output: 1 Explanation: row 1: 0 row 2: 01
Constraints:
1 <= n <= 30
1 <= k <= 2n - 1
Solutions
Solution 1: Recursion
Let's first observe the pattern of the first few rows:
n = 1: 0
n = 2: 0 1
n = 3: 0 1 1 0
n = 4: 0 1 1 0 1 0 0 1
n = 5: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
...
We can see that the first half of each row is exactly the same as the previous row, and the second half is the inversion of the previous row. Note that "inversion" here means changing $0$ to $1$ and $1$ to $0$.
If $k$ is in the first half, then the $k$-th character is the same as the $k$-th character of the previous row, so we can directly recurse with $kthGrammar(n - 1, k)$.
If $k$ is in the second half, then the $k$-th character is the inversion of the $(k - 2^{n - 2})$-th character of the previous row, i.e., $kthGrammar(n - 1, k - 2^{n - 2}) \oplus 1$.
The time complexity is $O(n)$, and the space complexity is $O(n)$.
Python3
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
if n == 1:
return 0
if k <= (1 << (n - 2)):
return self.kthGrammar(n - 1, k)
return self.kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1
Java
class Solution {
public int kthGrammar(int n, int k) {
if (n == 1) {
return 0;
}
if (k <= (1 << (n - 2))) {
return kthGrammar(n - 1, k);
}
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
}
}
C++
class Solution {
public:
int kthGrammar(int n, int k) {
if (n == 1) return 0;
if (k <= (1 << (n - 2))) return kthGrammar(n - 1, k);
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
}
};
Go
func kthGrammar(n int, k int) int {
if n == 1 {
return 0
}
if k <= (1 << (n - 2)) {
return kthGrammar(n-1, k)
}
return kthGrammar(n-1, k-(1<<(n-2))) ^ 1
}
TypeScript
function kthGrammar(n: number, k: number): number {
if (n == 1) {
return 0;
}
if (k <= 1 << (n - 2)) {
return kthGrammar(n - 1, k);
}
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
}