779. 第K个语法符号(mid)

题目描述

我们构建了一个包含 n \textit{n} n行( 索引从 1 1 1开始 )的表。首先在第一行我们写上一个 0 0 0。接下来的每一行,将前一行中的 0 0 0替换为 01 01 01 1 1 1替换为 10 10 10

例如,对于 n = 3 \textit{n} = 3 n=3,第 1 1 1行是 0 0 0,第 2 2 2行是 01 01 01,第3行是 0110 0110 0110
给定行数 n \textit{n} n和序数 k \textit{k} k,返回第 n \textit{n} n行中第 k \textit{k} k个字符。( k \textit{k} k 从索引 1 1 1开始)

  • 示例 1:
输入: n = 1, k = 1
输出: 0
解释: 第一行:0
  • 示例 2:
输入: n = 2, k = 1
输出: 0
解释: 
第一行: 0 
第二行: 01
  • 示例 3:
输入: n = 2, k = 2
输出: 1
解释:
第一行: 0
第二行: 01
  • 提示:
1 <= n <= 30
1 <= k <= 2^n - 1

思路介绍

题主的第一个想法也是直接模拟进行操作,但是肯定是不行的由于涉及到字符串的相加然后长度是每次倍增的所以使用大模拟的方法是不可行的。下面我们来仔细分析这个 n,k \textit{n,k} n,k是怎么来的:
假如我们要知道第 n n n行的 k k k个字符是多少,那么我们当然要知道第 n − 1 n-1 n1行的第 ( k + 1 ) / / 2 (k+1) // 2 (k+1)//2个字符是什么,这是因为从 n − 1 n-1 n1 n n n每一个字符到变成两个字符。这样子的话我们便可以使用递归来解决了,其中存在的一个问题就是可能给定的 k + 1 < 2 n k+1 < 2^n k+1<2n所以会出现考虑 i , 1 ( i ≠ 1 ) i, 1(i \neq 1) i,1(i=1)时,但是这个也简单因为每一行的开头都是 0 0 0,所以到这里问题就解决了。
代码如下:

class Solution:
    def kthGrammar(self, n: int, k: int) -> int:
        def recusive(i, j):
            if j == 1:
                return 0
            r = recusive(i-1, (j+1) // 2)
            if r == 1:
                if j % 2:
                    return 1
                else:
                    return 0
            else:
                if j % 2:
                    return 0
                else:
                    return 1
        return recusive(n, k)

你可能感兴趣的:(Leetcode刷题,leetcode,算法,职场和发展)