持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 10 天,点击查看活动详情。
第K个语法符号
原题地址
我们构建了一个包含 n 行( 索引从 1 开始 )的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。
例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。
给定行数 n 和序数 k,返回第 n 行中第 k 个字符。( k 从索引 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 <= 301 <= k <=- 1
思路分析
根据题目来找规律,算下每一行的值:
- 第一行:
0 - 第二行:
0 1 - 第三行:
01 10 - 第四行:
0110 1001 - 第五行:
01101001 10010110 - 第六行:
0110100110010110 1001011001101001
可以发现,每一行的前半段就是上一行,而后半段就是上一行每个值反过来,那么针对题目可以分两种情况处理,k 在上半段或下半段。
- 若 n 为1,那么返回值为0;
- 计算当前行的长度为 ;
- 如果 k 大于长度的一半,就在当前行的后半段,然后先得到上一行的值,位置为 k 在当前行后半段的位置,然后把得到的值反过来即可;
- 若 k 小于长度的一半,那么上一行 k 所在位置的值也为当前行所在位置的值。
AC 代码
/**
* @param {number} n
* @param {number} k
* @return {number}
*/
var kthGrammar = function(n, k) {
if(n === 1) return 0
var curLen = 2 ** (n - 1)
if(k > curLen / 2) {
var val = kthGrammar(n - 1, k - curLen / 2)
return val === 0 ? 1 : 0
} else {
return kthGrammar(n - 1, k)
}
};
结果:
- 执行结果: 通过
- 执行用时:56 ms, 在所有 JavaScript 提交中击败了86.67%的用户
- 内存消耗:41 MB, 在所有 JavaScript 提交中击败了37.78%的用户
- 通过测试用例:55 / 55