给定一个只有0's
且1's
的数组,找到具有相同数量0's
和1's
的最大子数组的长度。例如,给定一个数组
011110001
具有相同数量的0's
和1's
的最大子数组的长度为8,从索引0到索引7。
撰写递归函数largestSubarray
。这个函数有3个输入:一个数组--A,它的第一个元素的索引 - start,它的最后一个元素的索引 - 结束,并返回largestSubarray的大小。如果找不到具有相同数量的0's and 1's
的子数组,则该函数应返回0.
int largestSubarray(int * A, int start, int end){
int i, j=0, k=0;
for(i=start; i<=end; i++){
if(arr[i]==0){
j++;
}
else if(arr[i]==1){
k++;
}
if (j==k){
return (end+1-start)+largestSubarray(array, start+1, end);
}
}
如何修复此代码?请帮忙。感谢。
答案 0 :(得分:1)
目前还不清楚你是否解决了这个问题。递归可以为那些特别适合的任务提供优雅的解决方案,或者无法合理编写程序解决方案。每个递归调用都是一个单独的函数调用,需要一个完整的独立函数堆栈。随着递归次数的增加,这会迅速耗尽并耗尽可用内存。应该首选程序解决方案。
此外,您的数组011110001
必须是包含值
0, 1, 1, 1, 1, 0, 0, 0, 1
自己,011110001
,是2396161
的八进制常量。
在这里,找到零和一个最大的平衡子阵列可以通过循环轻松完成。但是,理解它是一个练习题考试,它具有教育价值。
一个干净的解决方案是编写一个largestsubarray
包装函数来调用第二个递归函数,传递size
的整数指针作为内部调用的额外参数。通过提供单个地址保持大小,可以消除在递归展开时覆盖值的可能性。
在单个函数中,关键是强制每个递归调用返回,否则在递归函数展开时会遇到覆盖size
的问题。一种实现可能是:
/* end must be ending index -- not size */
int largestsubarry (int *a, int start, int end)
{
int o = 0, z = 0; /* ones, zeros */
if (end <= start)
return 0;
/* count the ones and zeros in subarray */
for (register int i = start; i <= end; i++) {
if (a[i] == 1)
o++;
else if (a[i] == 0)
z++;
else
o = z = 0; /* reset on any other value */
}
if (o != z) { /* ones & zeros not equal */
int s = largestsubarry (a, start + 1, end), /* test eliminating */
e = largestsubarry (a, start, end - 1); /* each end */
if (s > e) /* return largest */
return s;
else
return e;
}
else /* balanced sub-array found, return size */
return o + z;
}
(注意:虽然不是错误,但C的标准编码样式避免使用camelCase
或MixedCase
变量名来支持所有 lower- case 同时保留大写名称以供宏和常量使用。这是一个风格问题 - 所以它完全取决于你,但没有遵循它可以导致某些圈子里的第一印象错误。)
示例使用/输出
传递包含以下值的整数数组会导致定位连续零和1的最大平衡子数组的正确大小,例如
$ ./bin/subarray
enter array (ctrl+d ends): 0 1 1 1 1 0 0 0 1
size: 8
$ ./bin/subarray
enter array (ctrl+d ends): 1 1 0 1 1 1 1 0 0 0 1
size: 8
$ ./bin/subarray
enter array (ctrl+d ends): 1 1 0 1 1 1 1 0 0 0 1 0
size: 10
$ ./bin/subarray
enter array (ctrl+d ends): 1 1 0 1 0 0 0 0 0 0 1
size: 6
$ ./bin/subarray
enter array (ctrl+d ends): 0 2 2 2 2 0 0 0 2
size: 0
可能有更有效的方法,但关键是知道要消除哪一端以找到最长的平衡子阵列。
答案 1 :(得分:0)
由于这显然是一个编码挑战,我只是提供一种方法来解决它。
end+1-start
,因为这是最长的平衡子数组。largestSubarray(array, start+1, end)
和largestSubarray(array, start, end-1)
递归致电,并返回最高的数字。可能有更有效的方法来解决它,但这是挑战的一部分!
修改
一个简单的改进是在计算1&0和0之前检查数组的长度。如果长度是奇数,则没有计算它们的点数(假设它们是数组中唯一可能的值),因此如果长度为奇数,您可以直接跳到第2步。