「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」
779. 第K个语法符号
在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。
给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)
「示例1:」
例子:
输入: N = 1, K = 1
输出: 0
输入: N = 2, K = 1
输出: 0
输入: N = 2, K = 2
输出: 1
输入: N = 4, K = 5
输出: 1
输入: N = 5, K = 2
输出: 1
输入: N = 5, K = 10
输出: 0
解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001
第五行: 0110100110010110
「注意: 」
N的范围[1, 30].K的范围[1, 2^(N-1)].
解题思路
我们可以写出来几行例子找一下他们之间的规律,然后我们就发现第n+1行的后半段是第n行的前半段相反的内容,我们可以用这个点来解一下这个题目
1. 由题意可知,我们除了第一行的其余行,都是根据上一行的内容来生成的,规则就是0转换成01,1转换为10
2. 如果行数等于1的话,我们可以直接返回0
3. 否则我们就可以求出来第n行的一个长度
4. 当前的这个k如果大于当前行一半的长度的时候,我们就取一个相反的值,并且递归调用
5. 当前行k小于当前行一半的长度,我们就取上一行改位置的值就可以了
代码实现
/**
* 779. 第K个语法符号
* @param {number} n
* @param {number} k
* @return {number}
*/
var kthGrammar = function (n, k) {
// 第一行内容: 0
// 第二行内容: 01
// 第三行内容: 0110
// 第四行内容: 01101001
if (n === 1) return 0; // 行数n=1的话直接 return一个0即可
let len = Math.pow(2, n - 1); // 求一下n行内容的一个长度
if (k > len / 2) {
//当前的这个k如果大于当前行一半的长度的时候,我们就取一个相反的值
let res = kthGrammar(n - 1, k - len / 2);
return res === 0 ? 1 : 0;
} else {
//当前行k小于当前行一半的长度,我们就取上一行改位置的值就可以了
return kthGrammar(n - 1, k);
}
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;