Leetcode 779. K-th Symbol in Grammar

Problem Explanation

We are given a row N, denoting the level of a '0-1' binary-generating tree. At row 1, we have a single node with value 0. For each subsequent row (from row 2), each node from the previous row generates two child nodes in the following way: a '0' node generates '0' on the left and '1' on the right, while a '1' node generates '1' on the left and '0' on the right. With this, we can build a binary tree.

The problem is to find the K-th value at the N-th row. All positions (K) are 1-indexed.

For example, let's consider N = 4, K = 5.

The binary tree for N = 4 would be as follows:

1
2
3                0
4              /   \
5            0       1
6          /   \   /   \
7        0       1 1     0
8      /   \   /   \   /   \
9    0       1 1     0 1     0

So, for N = 4, the sequence would be: 0 1 1 0 1 0 0 1. Therefore, the K-th (i.e., 5th) symbol in the sequence is 1.

Approach of solution

This problem can be solved using recursion. The main idea is that the result at row n, index k is related to the result at row n-1, index (k+1)/2 if k is odd and k/2 if k is even. This reasoning is based on the idea that a '0' at row n has descendants at row n+1 that match the pattern of row n, and a '1' at row n has descendants that are the reverse.

For example, if we have N=3, K=2, we can find that it's the same as N=2, K=1 but with opposite outcome.

Python Solution

1
2python
3class Solution:
4    def kthGrammar(self, N: int, K: int) -> int:
5        if N == 1: return 0
6        if K % 2 == 1: return self.kthGrammar(N-1, (K+1)//2)
7        else: return 1 - self.kthGrammar(N-1, K//2)

Java Solution

1
2java
3class Solution {
4 public int kthGrammar(int n, int k) {
5    if (n==1) return 0;
6    else if (k%2==1) return kthGrammar(n-1, (k+1)/2);
7    else return 1 - kthGrammar(n-1, k/2);
8 }
9}

JavaScript Solution

1
2javascript
3var kthGrammar = function(N, K) {
4    if (N === 1) return 0;
5    else if (K % 2 === 1) return kthGrammar(N-1, Math.floor((K+1)/2));
6    else return 1 - kthGrammar(N-1, Math.floor(K/2));
7};

C++ Solution

1
2C++
3class Solution {
4public:
5    int kthGrammar(int N, int K) {
6        if (N == 1) return 0;
7        else if (K % 2 == 1) return kthGrammar(N-1, (K+1)/2);
8        else return 1 - kthGrammar(N-1, K/2);
9    }
10};

C# Solution

1
2csharp
3public class Solution {
4    public int KthGrammar(int N, int K) {
5        if (N == 1) return 0;
6        else if (K % 2 == 1) return KthGrammar(N-1, (K+1)/2);
7        else return 1 - KthGrammar(N-1, K/2);
8    }
9}

In all the above solutions, we check if N equals 1, then return 0. This is because the first row only contains 0. For each subsequent row, we check if K is odd or even. If K is odd, we call the function with parameters (N-1, (K+1)/2). If K is even, we call the function with parameters (N-1, K/2) and invert the result by subtracting from 1, because the pattern of binary digits is reversed when coming from '1' parent node.## Complexity Analysis The time complexity of this solution is O(N) because we are reducing the problem size by almost half in each recursive call, and N is the maximum depth to which we will make recursive calls.

The space complexity is also O(N) because, in the worst case, we will push up to N recursive calls onto the system call stack.

We can illustrate this by considering that, in the worst case scenario, we need to go through all N levels of the binary tree to determine the Kth value. Therefore, our solution scales linearly with the size of the input variables, which allows it to handle large inputs effectively.

Key Takeaways

This problem presents a unique challenge incorporating knowledge of binary numbers, recursion, and tree-based algorithms. The key insight is understanding the recursive nature of the binary tree and how kth value of nth row is related to the values in (n-1)th row. From a practical standpoint, such problems can be useful in understanding how binary numbers are generated and manipulated, which is an important concept in computer science and digital circuits.

Moreover, solving such recursive problems can significantly improve your problem-solving abilities, as recursion involves thinking of the problem in a way that it can be broken down into smaller, more manageable parts, and then combining the results to form the solution. This is a fundamental technique in computer programming, particularly in fields like Artificial Intelligence and Machine Learning.


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫