题目
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
0
1
01
10
0110
1001
01101001
10010110
举例1
- N=5,K=8,所以它来自于上一行的第4个数,
- 上一行的第4个数,来自于再上一行的第2个数
- ...
- 也就是如果K为偶数,那么它来自于N-1行的k/2个数
举例2
- N=5,k=9,那它来自于上一行的第5个数
- 上一行的第5个数,来自于再上一行的第3个数
- ...
- 也就是如果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
}
};