在第一行我们写上一个 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)]
.
分析:
法一:使用递归,从前到后读取每一个字符,但是这种方法会超时(法一)
法二:使用递归,找到第K个字符的父亲,如果父亲是1,衍生的就是 10 ,K是单数就返回1,双数就返回0;
如果父亲是 0 ,衍生的就是 01 ,那么K是单数就返回 0,双数就返回 1
法一:
// 法一
class Solution {
public:
int kthGrammar(int N, int K) {
// 得到第n行的字符串
string num = get_row_n(N);
return num[K-1]-'0';
}
string get_row_n(int num){
if(num == 1)
return "0";
string result = get_row_n(num-1);
string read_num = "";
// 读取
for(int i=0;i<result.size();i++){
if(result[i] == '0')
read_num += "01";
else
read_num += "10";
}
return read_num;
}
};
法二:正确解法
class Solution {
public:
int kthGrammar(int N, int K) {
if(N==0)
return 0;
// 得到它的父亲
int result = kthGrammar(N-1,(K+1)/2);
return result==1?(K%2):1-(K%2);
// 上面这句话的意思是下面这一坨
// if(result == 1){
// // 偶数 10
// if(K%2 == 0)
// return 0;
// return 1;
// }else{
// // 偶数 01
// if(K%2 == 0)
// return 1;
// return 0;
// }
}
};