题目描述
在第一行我们写上一个 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
注意:
- N 的范围 [1, 30].
- K 的范围 [1, 2^(N-1)].
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/k-… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。
示例 2:
输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3
输出:[[1,2,3,4],[5,6,7],[8,9,10]]
解释:
输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。
提示:
- 链表中节点的数目在范围 [0, 1000]
- 0 <= Node.val <= 1000
- 1 <= k <= 50
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/sp… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
先使用了暴力解法,按照题干计算出最后一行,然后找到第n个字符,结果直接在30,434991989这个例子上内存爆炸
/**
* @param {number} n
* @param {number} k
* @return {number}
*/
var kthGrammar = function(n, k) {
let result="0";
while(n>0){
let list=result.split('').map((item)=>{
return item==='0'?"01":"10";
});
result=list.join('');
// console.log(result);
n--;
}
return result.charAt(k-1);
};
换种思路,先总结规矩,列举下前面几行
0
0|1
01|10
0110|1001
01101001|10010110
以上,会发现,下一行得前半段,就是和上一行完全相同
下一行得后半段是上一行反过来(0变成1,1变成0)
综上,我们可以从尾部开始递归,不停的推断最后一行得k位置在上一行的位置,直到第一行
代码
/**
* @param {number} n
* @param {number} k
* @return {number}
*/
var kthGrammar = function(n, k) {
//从最后一行倒推回去
//如果k在前半行 ,那就对应上一行第个值
// 如果在后半行,则找到在后半的位置,然后反转,就是对应的值
if(n===1) return 0;
let leng=2**(n-1);
if(k<=leng/2){
//前半
return kthGrammar(n-1,k);
}else{
//后半
let val=kthGrammar(n-1,k-leng/2);
return val===0?1:0;
}
};