持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
题目
我们构建了一个包含 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 <= 2^(n - 1)
思考
本题难度中等。
首先是读懂题意。给出一个包含 n 行的表,给定行数 n 和序数 k,返回第 n 行中第 k 个字符( k 从索引 1 开始)。
观察:
0
01
0110
01101001
01101001 10010110
01101001 10010110 10010110 01101001
找规律:
-
第 n 行的数字个数是
2^(n-1),是上一行数字的2倍。 -
每一行是由 上一行的数字 + 与上一行相反的数字 组成。
那么,我们可以使用递归的方法。如果 k 超过上一行的数字个数,则与上一行的数值相反;否则,与上一行的数值相同。
解答
方法一:找规律、递归
/**
* @param {number} n
* @param {number} k
* @return {number}
*/
var kthGrammar = function(n, k) {
if (k == 1) {
return 0
}
// 如果k超过上一行的数字个数,则与上一行值相反
if (k > (1 << n - 2)) {
return 1 ^ kthGrammar(n - 1, k - (1 << n - 2))
} else { // 与上一行值相同
return kthGrammar(n - 1, k)
}
}
// 执行用时:68 ms, 在所有 JavaScript 提交中击败了20.00%的用户
// 内存消耗:40.8 MB, 在所有 JavaScript 提交中击败了82.22%的用户
// 通过测试用例:55 / 55
复杂度分析:
- 时间复杂度:O(n),其中 n 为题目给定表的行数。
- 空间复杂度:O(n),其中 n 为题目给定表的行数,主要为递归的空间开销。