慕课地址: 《数据结构》 浙江大学 陈越、何钦铭
教材:
《数据结构》(第2版),陈越、何钦铭、徐镜春、魏宝刚、杨枨 编著,高等教育出版社
时间复杂度T(n): 占用存储单元的长度
空间复杂度S(n): 耗费时间的长度
平均复杂度
最坏情况复杂度(更常用)
复杂度的渐进表示:
复杂度分析例子——连续子列和问题:
算法1:求出所有子列和进行比较,每个都从子列初始算
三层for循环 T(N)=O(N^3)
算法2:求出所有子列和进行比较,相同的i不同的j保留j-1时的值,只需在其上加上Aj即可
两层for循环 T(N)=O(N^2)
算法3:分而治之
算法四:
#include "stdio.h"
#include "stdlib.h"
int maxsubseq(int K, int *seq);
int start, finish;
int main()
{
int K, i;
int *seq;
scanf("%d", &K);
seq = (int*)malloc(K*sizeof(int)); //seq数组保存完整的对象序列
for (i = 0; i<K; i++)
{
scanf("%d", &seq[i]);
}
printf("%d ", maxsubseq(K, seq)); //输出最大子序列和
printf("%d %d\n", seq[start], seq[finish]); //输出序列的首尾元素
free(seq);
// system("pause");
return 0;
}
int maxsubseq(int K, int *seq) //求最大子序列函数
{
int i, sum = 0, maxsum = 0, flag = 0;
for (i = 0; i<K; i++) //在该循环内判断序列中是否存在正数
{
if (seq[i]>0)flag = 1; //用flag标记,若存在正数则为1
}
if (flag == 0) //若不存在正数,则分为全负和有负有零两种
{
for (i = 0; i<K; i++) //若有负有零,例如:-1 -2 0 -3 0 。则输出应为:0 0 0。这里可以不用循环而直接设置输出,
{ //但题目的本意肯定还是让找出第一个零的位置,所以用一个循环找到start和finish
if (seq[i] == 0){ maxsum = 0; start = i; finish = i; return 0; }
}
maxsum = 0; start = 0; finish = K - 1; //若全为负则按照题意直接输出首尾元素
return 0;
}
for (i = 0; i<K; i++) //若序列中存在正数则按动归的思路求解子序列最大和maxsum
{
sum += seq[i];
if (sum<0)
{
sum = 0;
}
else if (sum>maxsum)
{
maxsum = sum; finish = i; //确定最后一个元素的下标;
}
}
sum = maxsum;
for (i = finish; i >= 0; i--) //由于子序列最大和为maxsum,所以只需将maxsum与前面各项相减到零即可确定第一个元素下标start
{ //由于题目中规定若有不只一组最大子序列和时输出start和finish较小的那一组,所以i要减到0。
sum -= seq[i]; //以防把前面相加等于零的子列忽略。若这里规定的是输出finish-start最小的一组,则在
if (sum == 0)start = i; //判断sum==0时退出循环即可
}
return maxsum;
}