最大子数组问题 时间复杂度为Θ(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;
}
#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;
}
相关文章推荐
- 算法导论-最大子数组问题-线性时间复杂度算法分析与实现
- 线性时间解决最大子数组问题
- 题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个 子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为 O(n)。
- 用分治法求最大子序列问题,时间复杂度O(N*logN)
- 数组连续子序列的最大的和-四种算法,四种时间复杂度
- 算法导论 4.1-5 最大子数组问题 线性时间算法 C++简单实现
- 一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和,求所有子数组的和的最大值,要求时间复杂度为O(n)。
- 求一个整数数组最大子数组之和,时间复杂度为N
- 最大子数组问题的递归和非递归(线性时间)代码
- 给定整型数组,其中每个元素表示木板的高度,木板的宽度都相同,求这些木板拼出的最大矩形的面积。并分析时间复杂度。
- 输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个 子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。
- 最大子数组问题---线性时间算法(转)
- 最大子序列和问题的求解(时间复杂度为O(N))
- 求所有子数组的和的最大值。要求时间复杂度为O(n)
- 约瑟夫问题的数学角度分析 C 数组实现 循环链表实现 递归实现时间复杂度O(logN)
- 动态规划求数组中和最大字串的值 以及 字符串的循环移位(要求空间复杂度O(1),时间复杂度O(n))
- 同时找出数组的最大值和最小值,要求时间复杂度为o(n)
- 给定整型数组,其中每个元素表示木板的高度,木板的宽度都相同,求这些木板拼出的最大矩形的面积。并分析时间复杂度。
- (C#)找出数组中最大子序列之和,分别以O(N^2),O(NlogN),O(N) 这3种时间复杂度求解
- 从一道求最大子列和问题分析时间复杂度