三种方法求出一个数组的最大字数组和
2013-07-10 23:27
225 查看
方法1:暴力法
遍历数组三次(i in 0..len, j in i..len, k in i..j),在第三次(k in i..j)求和sum+=data[k],并与当前max比较,大则更新max值,小max值不变
时间复杂度为O(n^3);
具体代码实现:
方法二:用分治算法解决
一个数组的最大字数组就存在于数组的三个位置,要么在数组的左半边,要么在数组的右半边,要么在数组的中间,而在数组的左右半边也符合该算法,可以用分治算法来解决
即 max_sum = max(left_max+right_max, max_sub_sum(l,m), max_sub_sum(m+1, h)) //m为每次数组的中间位置
时间复杂度为O(n*logn)
具体代码如下:
int max_two(int a, int b) { return (a>b ? a : b) ; }
int max_three(int a, int b, int c)
{
int max, temp[3] = {a, b, c};
max = temp[0];
for(int i=0; i<3; i++)
{
if(temp[i]>max)
max = temp[i];
}
return max;
}
int max_sub_sum(int *data, int l, int h)
{
if(l>h) return 0;
if(l==h) return max_two(data[0], 0);
int left_max=0, right_max=0, sum=0;
int i=0, m=(h+l)/2;
for(i=m; i>=l; i--)
{
sum += data[i];
left_max = max_two(left_max, sum);
}
sum = 0;
for(i=m+1; i<=h; i++)
{
sum += data[i];
right_max = max_two(right_max, sum);
}
return max_three(left_max+right_max, max_sub_sum(data, l, m), max_sub_sum(data, m+1, h));
}
方法三:遍历数组一遍,使用两个变量:maxendinghere 记录遍历过的元素之和与0比较后的最大值
maxsofar 记录当前字数组的最大值max(maxsofar, maxendinghere),与maxendinghere比较后的最大值
时间复杂度为O(n)
具体代码如下:
int max(int a, int b) { return (a>b ? a : b); }
int max_sub_sum(int *data, int len)
{
int maxsofar=0, maxendinghere=0;
for(int i=0; i<=len; i++)
{
maxendinghere = max(maxendinghere+data[i], 0);
maxsofar = max(maxsofar, maxendinghere);
}
return maxsofar;
}
对三种方法的运行时间进行比较,数组元素个数为1000
遍历数组三次(i in 0..len, j in i..len, k in i..j),在第三次(k in i..j)求和sum+=data[k],并与当前max比较,大则更新max值,小max值不变
时间复杂度为O(n^3);
具体代码实现:
int max(int a, int b) { return (a>b ? a : b); } int max_sub_sum(int *data, int len) { int sum=0, maxsofar=0; int i=0, j=0, k=0; for(i=0; i<=len; i++) { for(j=i; j<=len; j++) { sum=0; for(k=i; k<=j; k++) { sum += data[k]; maxsofar = max(maxsofar, sum); } } } return maxsofar; } int main(void) { const int SIZE = 1000; int i=0; int data[1000]; FILE *fp; fp = fopen("data1.txt", "r"); while(!feof(fp)) { if(feof(fp)) break; fscanf(fp, "%d", &data[i++]); } struct timeval start,end; gettimeofday(&start, NULL); int max_sum = max_sub_sum(data, SIZE-1); gettimeofday(&end, NULL); float t_time = end.tv_sec-start.tv_sec + (end.tv_usec-start.tv_usec)/1000000.0; cout << "time used: " << t_time << endl; cout << "the max is : " << max_sum << endl; return 0; }
方法二:用分治算法解决
一个数组的最大字数组就存在于数组的三个位置,要么在数组的左半边,要么在数组的右半边,要么在数组的中间,而在数组的左右半边也符合该算法,可以用分治算法来解决
即 max_sum = max(left_max+right_max, max_sub_sum(l,m), max_sub_sum(m+1, h)) //m为每次数组的中间位置
时间复杂度为O(n*logn)
具体代码如下:
int max_two(int a, int b) { return (a>b ? a : b) ; }
int max_three(int a, int b, int c)
{
int max, temp[3] = {a, b, c};
max = temp[0];
for(int i=0; i<3; i++)
{
if(temp[i]>max)
max = temp[i];
}
return max;
}
int max_sub_sum(int *data, int l, int h)
{
if(l>h) return 0;
if(l==h) return max_two(data[0], 0);
int left_max=0, right_max=0, sum=0;
int i=0, m=(h+l)/2;
for(i=m; i>=l; i--)
{
sum += data[i];
left_max = max_two(left_max, sum);
}
sum = 0;
for(i=m+1; i<=h; i++)
{
sum += data[i];
right_max = max_two(right_max, sum);
}
return max_three(left_max+right_max, max_sub_sum(data, l, m), max_sub_sum(data, m+1, h));
}
方法三:遍历数组一遍,使用两个变量:maxendinghere 记录遍历过的元素之和与0比较后的最大值
maxsofar 记录当前字数组的最大值max(maxsofar, maxendinghere),与maxendinghere比较后的最大值
时间复杂度为O(n)
具体代码如下:
int max(int a, int b) { return (a>b ? a : b); }
int max_sub_sum(int *data, int len)
{
int maxsofar=0, maxendinghere=0;
for(int i=0; i<=len; i++)
{
maxendinghere = max(maxendinghere+data[i], 0);
maxsofar = max(maxsofar, maxendinghere);
}
return maxsofar;
}
对三种方法的运行时间进行比较,数组元素个数为1000
相关文章推荐
- java快速寻找一个数组的最大值或最小值, min, max,三种方法
- JS判断一个数组中是否有重复值的三种方法
- JS判断一个数组中是否有重复值的三种方法
- 长度为n的数组,有一个数重复出现了n/2+1次,找出(三种方法)
- JS判断一个数组中是否有重复值的三种方法来自
- 电子科技大学推免复试题:利用递归方法找出一个数组中的最大值和最小值
- JavaScript之区别一个变量是数组还是变量的三种方法
- 求某一数组最大子数组和的三种方法
- 三种算法求解一个数组的子数组最大和
- c实现 求一个数组中最大子序列的和 (两种方法)
- JS判断一个数组中是否有重复值的三种方法
- 求解最大子数组问题的三种方法
- 给定只包含正数的数组,给出一个方法,将数组中的数拼接起来,得到的数,是最大的。
- JS判断一个数组中是否有重复值的三种方法
- 最大子数组问题的三种方法:分治法、暴力法和非递归方法
- JS判断一个数组中是否有重复值的三种方法
- 三种算法求解一个数组的子数组最大和
- 求一个数组当中最大(最小)值的两种计算方法
- 三种算法求解一个数组的子数组最大和