comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
中等 |
|
我们构建了一个包含 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 <= 30
1 <= k <= 2n - 1
我们先来看一下前几行的规律:
n = 1: 0
n = 2: 0 1
n = 3: 0 1 1 0
n = 4: 0 1 1 0 1 0 0 1
n = 5: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
...
可以发现,每一行的前半部分和上一行完全一致,后半部分是上一行的反转。注意,这里的“反转”指的是
如果
如果
时间复杂度
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
if n == 1:
return 0
if k <= (1 << (n - 2)):
return self.kthGrammar(n - 1, k)
return self.kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1
class Solution {
public int kthGrammar(int n, int k) {
if (n == 1) {
return 0;
}
if (k <= (1 << (n - 2))) {
return kthGrammar(n - 1, k);
}
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
}
}
class Solution {
public:
int kthGrammar(int n, int k) {
if (n == 1) return 0;
if (k <= (1 << (n - 2))) return kthGrammar(n - 1, k);
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
}
};
func kthGrammar(n int, k int) int {
if n == 1 {
return 0
}
if k <= (1 << (n - 2)) {
return kthGrammar(n-1, k)
}
return kthGrammar(n-1, k-(1<<(n-2))) ^ 1
}
题目中索引从
仔细观察,一行中的第
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
如果第
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
^ * *
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
^ * *
可以发现,第
因此,我们只需要看
最后判断反转的次数是否为奇数,是则答案为
以上累计反转次数的过程,实际上等价于求
时间复杂度
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
return (k - 1).bit_count() & 1
class Solution {
public int kthGrammar(int n, int k) {
return Integer.bitCount(k - 1) & 1;
}
}
class Solution {
public:
int kthGrammar(int n, int k) {
return __builtin_popcount(k - 1) & 1;
}
};
func kthGrammar(n int, k int) int {
return bits.OnesCount(uint(k-1)) & 1
}