Problem Statement
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
, the 1st row is0
, the 2nd row is01
, and the 3rd row is0110
.
Given two integer n
and k
, return the kth
(1-indexed) symbol in the nth
row of a table of n rows.
Examples
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
Here is row 2, at index 1 is 0, while at index 2 is 1.
Example 3:
Input: n = 2, k = 2
Output: 1
Explanation:
row 1: 0
row 2: 01
Here in row 2, at index 2 is 1.
Different Approaches
Intuition
The problem revolves around understanding how the grammar sequence is constructed:
- Starting from
0
, each subsequent row is formed by replacing0
with01
and1
with10
. - As a result, the sequence grows exponentially, and we cannot generate the full sequence for large values of
n
efficiently. Instead, we can use a recursive approach to directly determine the k-th symbol without constructing the whole sequence.
Approach
- Recursive Definition:
- If
n = 1
, the sequence is simply0
. Therefore, the k-th symbol is0
. - For
n > 1
, the sequence at rown
has a length of2^(n-1)
. We can split this sequence into two halves:- The first half (length
2^(n-2)
) is identical to the sequence of rown-1
. - The second half (length
2^(n-2)
) is the complement of the sequence of rown-1
.
- The first half (length
- To find the k-th symbol in the n-th row:
- If
k
is in the first half, the k-th symbol is the same as in the(n-1)
-th row. - If
k
is in the second half, the k-th symbol is the complement of the symbol in the(k - mid)
position of the(n-1)
-th row.
- If
- This observation allows us to recursively determine the k-th symbol in O(n) time.
- If
Code:
#include <iostream>
using namespace std;
// Function to determine the k-th symbol in the n-th row
int kthSymbolInGrammar(int n, int k) {
// Base case: If we're at the first row, the only symbol is 0
if (n == 1 && k == 1) return 0;
// Find the length of the row
int mid = (1 << (n - 1)) / 2; // 2^(n-1) / 2
// If k is less than or equal to mid, the symbol is the same as in the first half
if (k <= mid) {
return kthSymbolInGrammar(n - 1, k);
} else {
// Otherwise, it's the complement of the corresponding symbol in the first half
return !kthSymbolInGrammar(n - 1, k - mid);
}
}
int main() {
int n, k;
cout << "Enter n: ";
cin >> n;
cout << "Enter k: ";
cin >> k;
cout << "The " << k << "-th symbol in the " << n << "-th row is: "
<< kthSymbolInGrammar(n, k) << endl;
return 0;
}