递归公式推导法:
我们可以知道第n行有2n-1个字符,其中前2(n-1)-1个字符是上一个字符串的值,第2(n-1)个是新加的1,后面2(n-1)-1个字符是上一个字符串翻转取反得来的。
那么对于给定的n和k,我们只需求这个位置的k最初是由之前哪次的字符串的哪个字符变来的,并计算被反转的次数,我们就能得到当前k是啥。
每次递归中三种情况:
1.如果k>2^(n-1),说明它是上一个字符串翻转(因为是翻转会生成的后半段,所以其位置=2 ^ (n-1)-k而不是直接是k!!!)并invert过来的部分,可以推导得到求出它在上一个字符串的位置索引为2^n-k,并将invert次数加一次,当此时n>1则可以接着递归求下去;
2.如果k<2^(n-1),说明它就是上一次字符串位置k处的字符,没有被invert则不必更新invert次数,当此时n>1则可以接着递归求下去;
3.如果k==2^(n-1),说明他是此时对应的n新增的最中间1,可以结束递归,返回其初始值1。另一种情况递归结束条件为n递归到1了,说明它就是最初始的值0,返回0;
得到其初始值后,再来结合这个值被invert了几次,奇数次则原值0变1或1变0,偶数次就不变直接返回初始值。
class Solution {
/*
思想:Sn = Sn-1 + '1' + Sn-1各字符取反然后逆置的结果
*/
public char findKthBit(int n, int k) {
if(n==1)return '0';
int mid = (int)Math.pow(2,n-1);
if(k==mid)return '1';
else if(k<mid){
return findKthBit(n-1, k);
}else{//去s(n-1)中找第(mid-(k-mid))个数【对称的找】,然后返回它的翻转值
k-=mid;
k = mid - k;
return findKthBit(n-1, k) =='0'?'1':'0';//进行翻转
}
}
}