Medium级别的题: 给定n和k两个正整数,定义二进制串Sn如下,
s(1) = "0"
s(i) = s(i - 1) + "1" + reverse(invert(s(i - 1))) 对于i > 1
其中reverse表示翻转顺序,而invert表示每一位取反(‘0’变为‘1’, ‘1’变为’0‘)
例如
s(1) = "0"
s(2) = "011"
s(3) = "0111001"
s(4) = "011100110110001"
求s(n)的第k位。
数据范围: 1 <= n <= 20, 1 <= k <= 2 ^ n - 1
例如n = 3, k = 1, 输出‘0’
因为s(3) = "0111001"
分析:无聊题。数据范围那么小——串长组大2 ^ n - 1 <= 2 ^ 20 - 1 = 1048575,可以直接暴力解决。
代码:
class Solution {public: char findKthBit(int n, int k) { string s = "0"; for (int i = 2; i <= n; ++i) { string temp = s; for (char &c : temp) { c = '1' - c + '0'; } reverse(temp.begin(), temp.end()); s += "1" + temp; } return s[k - 1]; }};
聪明一点的做法,可以解决n较大的问题。
如果求s(n)的第k位,我们看一下它如果是“中间”,则直接返回1。
否则如果它在前半段,则相当于求s(n - 1)的第k位。
如果它在后半段,其实构造过程后半段相当于是取反“回文”的,所以转换一下,它相当于求s(n - 1)第k'位,再取反。
代码:
class Solution {public: char findKthBit(int n, int k) { if (n == 1) return '0'; const int half = 1 << (n - 1); if (k == half) return '1'; return (k < half) ? findKthBit(n - 1, k) : ('1' - (findKthBit(n - 1, half - (k - half)) - '0')); }};