您的位置:首页 > 其它

最大子数组问题 时间复杂度为Θ(n)

2013-04-03 17:24 393 查看
《算法导论》中提出的一个解题思路,从数组的左边界开始,由左至右处理,记录到目前为止已经处理过的最大子数组。若已知A[1..j]的最大子数组基于如下性质将解扩展为A[1..j+1]的最大子数组:A[1..j+1]的最大子数组要么是A[1..j]的最大子数组,要么是某个子数组A[i..j+1](1≤i≤j+1)。在已知A[1..j]的最大子数组的情况下,可以在线性时间内找出形如A[i..j+1]的最大子数组。该算法的时间复杂度为因此该算法的时间复杂度为Θ(n)

#include <stdio.h>
#include <string.h>

struct subarray {
int start;
int end;
int sum;
};

#define max(__x, __y) ((__x) > (__y) ? (__x) : (__y))

static void max_sumarray(int *a, int len, void *p)
{
struct subarray *sa = (typeof(sa))p;
int i;
int max_sum, prev, tmp;
int start, end;

if (!sa || (len <= 0)) {
fprintf(stderr, "Invalid argument.\n");
return;
}

memset(sa, 0, sizeof(*sa));

max_sum = a[0];
prev = a[0];
start = end = 0;
for (i = 1; i < len; ++i) {
prev = max(a[i], prev + a[i]); //寻找以当前位置为结尾的最大子串

if (prev < max_sum) {

    /**

    **如果以当前位置为结尾的最大子串是其本身,则下次扫描时以当前位置为结尾的最大子串的起始位置为本位置

    **/ 
if (prev == a[i]) {
start = i;
}
continue;
}

max_sum = prev;

if (prev == a[i]) {
sa->start = sa->end = i;
} else {
sa->start = start;
sa->end = i;
}
}

sa->sum = max_sum;
}

int main(void)
{
int source[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
struct subarray sa;

max_sumarray(source, sizeof(source) / sizeof(source[0]), &sa);
printf("Max sum: %d, start: %d, end: %d.\n", sa.sum, sa.start, sa.end);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐