我有一个遵循特定逻辑的二进制序列
它以0
和
第n项=第(n-1)项的序列+ 0
+逆(第(n-1)项)
例如:
0
0 + 0 + 1
001 + 0 + 011
0010011 + 0 + 0011011
在这里,我需要找出第k个序列的第n个项。
我的看法:
我已经编写了一个递归函数来计算第k个序列中的术语数
public static long noOfElements(long elements){
long answer;
if(elements == 1)
return 1;
else
answer = 1 + 2*noOfElements(elements-1);
return answer;
}
经过分析,我发现序列遵循一定的模式,第k个序列可以分解为一半并且切换0和1的值我可以跟踪结果。
所以,我的函数在下面将给定的序列分解为[0,0,1]递归
public static long letsBegin(long reqd, long length){
long mid = (length + 1)/2;
if(length <= 3){
return reqd;
}else{
if(reqd > mid){
reqd = reqd - 2*(reqd-mid);
switcher(); //Switcher stores if the value is switched
return letsBegin(reqd, mid);
}else{
return letsBegin(reqd, mid);
}
}
}
最后我在[0,0,1]中有索引1,2或3,我相应地输出了值。 这里的问题是
答案 0 :(得分:1)
Easily done with recursion, the number of elements in k-th sequence is 2^(k+1)-1
:
static int foo(long n, int k) { //n-th element (indexed from 0) in k-th sequence
long length = (2L << k) - 1; // computes 2^(k+1)-1
if(n >= length) return -1; // prevent invalid inputs
if(n == length/2) return 0; // middle point
if(n < length/2) return foo(n, k-1); //left half
return 1 - foo(length - n - 1, k-1); //right half
}
In the last recursive call, you both flip the array and the return value.
EDIT:
Be sure to use (2L << k)
and not (2 << k)
otherwise this will cause overflow and may lead to endless recursion.
答案 1 :(得分:0)
你错过了一个案例(当reqd == mid)并且调用递归函数时长度不正确(mid而不是mid-1)。完成这些修复后,函数如下所示:
public static long letsBegin(long reqd, long length){
long mid = (length + 1)/2;
if(length <= 3){
return reqd;
} else{
if(reqd > mid){
reqd = reqd - 2*(reqd-mid);
switcher(); //Switcher stores if the value is switched
return letsBegin(reqd, mid-1);
} else if(reqd < mid) {
return letsBegin(reqd, mid-1);
} else {
return 0;
}
}
}
此外,代码比必要的更复杂。请尝试使用以下重复关系:
T(n, k) = T(n, k-1) if n < 2^{k-1}
= 0 if n = 2^{k-1}
= 1 - T(2^k-n, k-1) otherwise