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

770 阅读2分钟

「这是我参与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
注意:
  1. N 的范围 [1, 30].
  2. 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);
  }
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;