[路飞]_leetcode刷题_779. 第K个语法符号

292 阅读2分钟

题目

779. 第K个语法符号

在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)

例子:

输入: N = 1, K = 1
输出: 0

输入: N = 2, K = 1
输出: 0

输入: N = 2, K = 2
输出: 1

输入: N = 4, K = 5
输出: 1

解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001

思路1:

找到每1行生成字符的规律,然后去生成每一行的字符串,生成完第N行后,取第k个数即可

但是,由于这是成指数即增长的,N每加1,字符串长度都会翻倍, 2**30 == 1073741824,

即输入30,则字符串长度会有10亿多,所以这种思路肯定是不行的。

思路2:

找规律,递归

我们先画个图

0
01
0110
01101001
0110100110010110

举例1

  1. N=5,K=8,所以它来自于上一行的第4个数,
  2. 上一行的第4个数,来自于再上一行的第2个数
  3. ...
  4. 也就是如果K为偶数,那么它来自于N-1行的k/2个数

举例2

  1. N=5,k=9,那它来自于上一行的第5个数
  2. 上一行的第5个数,来自于再上一行的第3个数
  3. ...
  4. 也就是如果k为奇数,那么它来自于N-1行的(k+1)/2个数

两者结合在一起,也就是第K个数,来自于上一行的Math.floor((k+1)/2)

接下来我们看当前数字是0还是1的决定条件

如果上一行为0,那么k为基数的话就是0,为偶数就是1,也就是1-(k%2) 如果上一行为1,那么k为基数的话就是1,为偶数就是0, 也就是k%2

代码如下:

/**
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
var kthGrammar = function(N, k) {
    if (N == 1) return 0;
    let temp = kthGrammar(N-1, Math.floor((k+1)/2));
    if(temp == 0){
        return 1-(k%2)
    }else{
        return k%2
    }
};