最大和连续子数组使用递归直接输出结果
largest sum contiguous sub array using recursion to directly output result
是否可以使用递归找到最大总和的连续子数组,这样函数将直接 return 输出。
下面是我的解决方案,我存储了以每个索引结尾的最大子数组,然后在 print() 函数中找到最大的子数组。但是,我想要以下内容
- 使用递归
- 使用递归函数直接输出最终结果
我的代码使用递归函数和辅助 print() 函数来查找这些数字中的最大值
#include <stdio.h>
//int a[] = {-6,60,-10,20};
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int main(void)
{
fun(len-1);
printf("max sub array == %d\n",print(maxherearray));
printf("\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[n];
maxherearray[n] = max(a[n], a[n]+fun(n-1));
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
编辑:发布我不知何故错过的 print() 函数
//Please make sure that #include <limits.h> is added
int print(int a[])
{
int i = 0;
int largest = INT_MIN;
printf("largest == %d\n",largest);
for(i=0;i<len;i++)
{
if(a[i] > largest)
largest = a[i];
}
return largest;
}
引入两个全局变量start_idx
和end_idx
来跟踪最大连续子数组的开始和结束索引。在递归函数中相应地更新这些变量。
#include <stdio.h>
/* int a[] = {-6,60,-10,20}; */
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int fun(int n);
int max(int a, int b);
int find_max(int a[], int len);
void print_array(int a[], int start_idx, int end_idx);
int start_idx = 0; // Start of contiguous subarray giving max sum
int end_idx = 0; // End of contiguous subarray giving max sum
#define NEG_INF (-100000)
int max_sum = NEG_INF; // The max cont sum seen so far.
int main(void)
{
start_idx = 0;
end_idx = len - 1;
maxherearray[0] = a[0];
printf("Array a[]: ");
print_array(a, 0, len-1);
printf("\n");
// Compute the necessary information to get max contiguous subarray
fun(len - 1);
printf("Max subarray value == %d\n", find_max(maxherearray, len));
printf("\n");
printf("Contiguous sums: ");
print_array(maxherearray, 0, len - 1);
printf("\n");
printf("Contiguous subarray giving max sum: ");
print_array(a, start_idx, end_idx);
printf("\n\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[0];
int max_till_j = fun(n - 1);
// Start of new contiguous sum
if (a[n] > a[n] + max_till_j)
{
maxherearray[n] = a[n];
if (maxherearray[n] > max_sum)
{
start_idx = end_idx = n;
max_sum = maxherearray[n];
}
}
// Add to current contiguous sum
else
{
maxherearray[n] = a[n] + max_till_j;
if (maxherearray[n] > max_sum)
{
end_idx = n;
max_sum = maxherearray[n];
}
}
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
// Print subarray a[i] to a[j], inclusive of end points.
void print_array(int a[], int i, int j)
{
for (; i <= j; ++i) {
printf("%d ", a[i]);
}
}
int find_max(int a[], int len)
{
int i;
int max_val = NEG_INF;
for (i = 0; i < len; ++i)
{
if (a[i] > max_val)
{
max_val = a[i];
}
}
return max_val;
}
总的来说,你的算法逻辑是可以的。就像,
f(0) = a(i);
f(i) = max(f(i-1) + a(i), a(i));
,得到中间的结果数组
max(0, f(1), f(2), ... , f(n-1))
,得到最终的max_sub结果
并且您为#2 设计了一个名为fun
的函数,为#3 设计了一个名为a helper print()
的函数。
现在,(我猜)您想要将 #2 和 #3 组合在一起,即利用 #2 的中间结果来避免额外的 computing/memory space。根据你原来的算法逻辑,这里有一些可能的方式,比如
在您的 fun
中添加一个参数以保持 max_sub 结果
int fun(int n, int *result)// add int *result to return max_sub
{
int max_here = 0;
if(n==0){
return a[n];
}
max_here = max(a[n],a[n]+fun(n-1, result));
*result = max(*result, max_here);
return max_here;
}
//...
int main(void)
{
int result = 0;
fun(len-1, &result);
printf("max sub : %d\n", result);
}
使用全局变量(哦!)及时得到max_sub
int g_maxhere = 0;
int fun2(int n)
{
if(n==0){
return a[n];
}
g_maxhere = max(g_maxhere, max(a[n],a[n]+fun2(n-1)));
return max(a[n], a[n]+fun2(n-1));
}
//...
int main(void)
{
fun2(len-1);
printf("max sub:%d\n",g_maxhere)
}
其实你原来使用辅助函数的方案可以让你的算法更清晰。
是否可以使用递归找到最大总和的连续子数组,这样函数将直接 return 输出。
下面是我的解决方案,我存储了以每个索引结尾的最大子数组,然后在 print() 函数中找到最大的子数组。但是,我想要以下内容
- 使用递归
- 使用递归函数直接输出最终结果
我的代码使用递归函数和辅助 print() 函数来查找这些数字中的最大值
#include <stdio.h>
//int a[] = {-6,60,-10,20};
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int main(void)
{
fun(len-1);
printf("max sub array == %d\n",print(maxherearray));
printf("\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[n];
maxherearray[n] = max(a[n], a[n]+fun(n-1));
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
编辑:发布我不知何故错过的 print() 函数
//Please make sure that #include <limits.h> is added
int print(int a[])
{
int i = 0;
int largest = INT_MIN;
printf("largest == %d\n",largest);
for(i=0;i<len;i++)
{
if(a[i] > largest)
largest = a[i];
}
return largest;
}
引入两个全局变量start_idx
和end_idx
来跟踪最大连续子数组的开始和结束索引。在递归函数中相应地更新这些变量。
#include <stdio.h>
/* int a[] = {-6,60,-10,20}; */
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int fun(int n);
int max(int a, int b);
int find_max(int a[], int len);
void print_array(int a[], int start_idx, int end_idx);
int start_idx = 0; // Start of contiguous subarray giving max sum
int end_idx = 0; // End of contiguous subarray giving max sum
#define NEG_INF (-100000)
int max_sum = NEG_INF; // The max cont sum seen so far.
int main(void)
{
start_idx = 0;
end_idx = len - 1;
maxherearray[0] = a[0];
printf("Array a[]: ");
print_array(a, 0, len-1);
printf("\n");
// Compute the necessary information to get max contiguous subarray
fun(len - 1);
printf("Max subarray value == %d\n", find_max(maxherearray, len));
printf("\n");
printf("Contiguous sums: ");
print_array(maxherearray, 0, len - 1);
printf("\n");
printf("Contiguous subarray giving max sum: ");
print_array(a, start_idx, end_idx);
printf("\n\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[0];
int max_till_j = fun(n - 1);
// Start of new contiguous sum
if (a[n] > a[n] + max_till_j)
{
maxherearray[n] = a[n];
if (maxherearray[n] > max_sum)
{
start_idx = end_idx = n;
max_sum = maxherearray[n];
}
}
// Add to current contiguous sum
else
{
maxherearray[n] = a[n] + max_till_j;
if (maxherearray[n] > max_sum)
{
end_idx = n;
max_sum = maxherearray[n];
}
}
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
// Print subarray a[i] to a[j], inclusive of end points.
void print_array(int a[], int i, int j)
{
for (; i <= j; ++i) {
printf("%d ", a[i]);
}
}
int find_max(int a[], int len)
{
int i;
int max_val = NEG_INF;
for (i = 0; i < len; ++i)
{
if (a[i] > max_val)
{
max_val = a[i];
}
}
return max_val;
}
总的来说,你的算法逻辑是可以的。就像,
f(0) = a(i);
f(i) = max(f(i-1) + a(i), a(i));
,得到中间的结果数组max(0, f(1), f(2), ... , f(n-1))
,得到最终的max_sub结果
并且您为#2 设计了一个名为fun
的函数,为#3 设计了一个名为a helper print()
的函数。
现在,(我猜)您想要将 #2 和 #3 组合在一起,即利用 #2 的中间结果来避免额外的 computing/memory space。根据你原来的算法逻辑,这里有一些可能的方式,比如
在您的
fun
中添加一个参数以保持 max_sub 结果int fun(int n, int *result)// add int *result to return max_sub { int max_here = 0; if(n==0){ return a[n]; } max_here = max(a[n],a[n]+fun(n-1, result)); *result = max(*result, max_here); return max_here; } //... int main(void) { int result = 0; fun(len-1, &result); printf("max sub : %d\n", result); }
使用全局变量(哦!)及时得到max_sub
int g_maxhere = 0; int fun2(int n) { if(n==0){ return a[n]; } g_maxhere = max(g_maxhere, max(a[n],a[n]+fun2(n-1))); return max(a[n], a[n]+fun2(n-1)); } //... int main(void) { fun2(len-1); printf("max sub:%d\n",g_maxhere) }
其实你原来使用辅助函数的方案可以让你的算法更清晰。