问题描述

求取数组中最大连续子序列和,例如给定数组为A={1, 3, -2, 4, -5}, 则最大连续子序列和为6,即1+3+(-2)+ 4 = 6。

(一)穷举法no.1

穷举式的尝试所有可能,这里就不多做解释,这里的算法复杂度易得为O(N^3).

#include<stdio.h>int MaxSubSequenceSum(const int A[], int N){int ThisSum, MaxSum, i, j,k;MaxSum = 0;for(i=0;i < N; i++){for(j=i;j < N;j++){ThisSum = 0;for(k=i;k <= j;k++){ThisSum += A[k];if(ThisSum > MaxSum){MaxSum = ThisSum;}  }}}return MaxSum;
}   int main(){int number[6];int result;for(int i=0;i<6;i++){scanf("%d", &number[i]); //在这里%d后不可以添加\n,因为这会造成编译器会在读取一次\n;}result = MaxSubSequenceSum(number, 6);printf("result = %d\n", result);return 0;
}

(二)穷举法no.2

分析上面的算法可知,在上述情况下会产生大量重复的运算,譬如在第三层循环中,该算法过分耗时了,所以我们可以通过撤销一个for循环,来降低上述的算法的复杂度。因为消除了一个for循环,所以也易得上述算法复杂度为O(N^2)。

#include<stdio.h>int MaxSubSequenceSum(const int A[], int N){int ThisSum, MaxSum, i, j,k;MaxSum = 0;for(i=0;i < N; i++){ThisSum = 0;for(j=i;j < N;j++){ThisSum += A[j];if(ThisSum > MaxSum){MaxSum = ThisSum;}}}return MaxSum;
}   int main(){int number[6];int result;for(int i=0;i<6;i++){scanf("%d", &number[i]); //在这里%d后不可以添加\n,因为这会造成编译器会在读取一次\n;}result = MaxSubSequenceSum(number, 6);printf("result = %d\n", result);return 0;
}

(三)递归以及分治法

让我们按照这样的思路进行思考?。在上述问题中,最大子序列的和只可能在三处地方出现(需要先将所有输入分为两个部分,左半部分亦或右半部分)。即或者整个出现在输入数据的左半部分,或整个出现在输入数据的右半部分,或者整个跨越输入数据的中部从而占据左右两半部分。前两中情况我们可以采用递归求解的方式,而第三种情况的最大和可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的最后一个元素)而得到。然后将这两个和加在一起,即为第三中情况之和。易知,分治法的复杂度为O(logn),又因为for循环最多只有一层,虽然存在两次,所以该算法的复杂度为O(NlogN)。

#include <stdio.h>static int MaxSubSum(const int A[], int Left, int Right){int MaxLeftSum, MaxRightSum;int MaxLeftBorderSum, MaxRightBorderSum;int LeftBorderSum, RightBorderSum;int Center, i;if(Left == Right){if (A[Left]>0){return A[Left];}else{return 0;}}Center = (Right + Left)/2;MaxLeftSum = MaxSubSum(A, Left, Center);MaxRightSum = MaxSubSum(A, Center+1, Right);MaxLeftBorderSum = 0; MaxRightBorderSum = 0;for (i = Center; i >= Left; i--){LeftBorderSum += A[i];if (LeftBorderSum > MaxLeftBorderSum){MaxLeftBorderSum = LeftBorderSum;}}for (i = Center+1; i <= Right; i++){RightBorderSum += A[i];if (RightBorderSum > MaxRightBorderSum){MaxRightBorderSum = RightBorderSum;}}return Max3(MaxLeftSum, MaxRightSum, MaxRightBorderSum + MaxLeftBorderSum);
}   int MaxSubSequenceSum(const int A[ ], int N){return MaxSubSum(A, 0, N-1);}int main(){int number[6];int result;for(int i=0;i<6;i++){scanf("%d", &number[i]); //在这里%d后不可以添加\n,因为这会造成编译器会在读取一次\n;}result = MaxSubSequenceSum(number, 6);printf("result = %d\n", result);return 0;
}

(四)联机算法

该算法只对数据进行一次扫描,一旦A[ i ]被读入并被处理,它就不再需要被记忆。分析该算法容易知道,因为该问题不需要最大序列和的坐标输出,所以我们不需要记忆序列位置,仅仅记忆当前最大序列和的值即可。并且该问题又是线性相加,不存在错位相加,所以使用该算法就可以在复杂度为O(N)下得到,下面看代码。

#include <stdio.h>int MaxSubSequenceSum(const int A[ ], int N){int ThisSum, MaxSum, j;ThisSum = MaxSum = 0;for (j= 0; j < N; j++){ThisSum += A[j];if (ThisSum > MaxSum){MaxSum = ThisSum;}else if(ThisSum < 0){ThisSum = 0;}}return MaxSum;}int main(){int number[6]; //这里自己设置int result;for(int i=0;i<6;i++){scanf("%d", &number[i]); //在这里%d后不可以添加\n,因为这会造成编译器会在读取一次\n;}result = MaxSubSequenceSum(number, 6);printf("result = %d\n", result);return 0;
}

最大子序列和问题的四种解法以及解析相关推荐

  1. 四种解法——求子序列的最大连续子序和(普通解法、求和解法、分治法、O(n)级解法)(面试经典题)

    励志用少的代码做高效表达 在这四种解法里,解法一是通法,可以学到规律和知识,做基础之用:解法二在解法一的基础上做改进,锻炼思维:解法三则是大名鼎鼎的分治法,涉及到递归的知识,算是"高效算法设 ...

  2. 算法-寻找数组中的重复值,四种解法

    算法-寻找数组中的重复值 寻找数组中的重复值 寻找数组中的重复值 题目来源于:Leetcode-287.本题归类到简单我无法理解-要满足四个条件需要用很特定的解法,面试中要是用到的话很可能是在给自己挖 ...

  3. python整数拆分dp算法_整数拆分问题的四种解法【转载】

    http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 整数划分问题是 ...

  4. 奖券数目c语言答案,2015 年蓝桥杯 C 语言 B 组省赛第 1 题: 奖券数目 (四种解法 + 详细分析)...

    题目 奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利. 虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码 ...

  5. 【剑指Offer】剪绳子问题——四种解法

    剪绳子问题--四种解法 题目描述: 输入描述: 返回值描述: 示例1: 解题思路: 方法1:暴力递归 方法2:记忆化递归 方法三:动态规划 方法四,数学原理 题目描述: 给你一根长度为n的绳子,请把绳 ...

  6. 销售额超过公司均值的优秀经销商?SQL比例问题之分组比较的四种解法

    分组比较是看起来比较简单,但是写起来比较麻烦的问题,一般就是先进行两个不同分组计数.求和.求均值,然后两个均值作比较,这样就涉及表连接和判断,写的代码量就比其他问题多很多.它与连续问题.排名问题和累加 ...

  7. 最长公共子序列长度的四种解法

    一.题目:求两个字符序列的最长公共字符子序列.给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB, ...

  8. 八皇后问题详解(四种解法)

    所有源码都在github上(https://github.com/seasonyao/eight_queen_question) 如果你去百度百科八皇后这个问题,你会发现人家也是历史上有头有脸的一个问 ...

  9. 青蛙跳台阶c语言递归函数,青蛙跳台阶问题的四种解法

    http://raychase.iteye.com/blog/1337359 题目:一只青蛙一次可以跳1级台阶,也可以跳2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 这道题还被ITEye放在了博 ...

最新文章

  1. 图解Oracle RMAN备份入门
  2. Scala基础教程(五):函数、闭包
  3. 一般屏幕的3D模型是公开的吗?
  4. (六)docker-compose使用教程
  5. hadoop综述_Hadoop书籍赠品–综述
  6. 系统中已安装了vmware,请先卸载干净并重启电脑
  7. 《HTML5与CSS3实战指南》——2.3 HTML5常见问题
  8. 安卓ondraw刷新视图_android播放动画时是否会调用被操作的视图的onDraw方法?
  9. (笔试题)被3和5整除的数的和
  10. Android应用APP: 基于MobileNet和EfficientNet的图像分类模型_调试运行以及打包Tensorflow官方提供的Image classification demo
  11. AIX下内存泄漏的监控
  12. 被final关键字坑了
  13. linux 卸载theano,centos 安装theano
  14. Shenyu网关本地打docker镜像包
  15. vue中transition动画实现淡入淡出
  16. 穷人的语义处理工具箱之二:语义编辑距离
  17. U-Boot 图形化配置
  18. sws_getContext和sws_scale分析
  19. LittleVGL(LVGL)学习笔记——PC 模拟器的安装和使用(CodeBlocks)
  20. 《趣味知识博文》小W与小L带你聊天式备考CDA Level Ⅰ(二)

热门文章

  1. golang 压缩算法 gzip/lz4 对比
  2. 电脑关机很慢很慢的解决办法(Windows XP)
  3. S5PV210 Study210开发板刷系统
  4. 推荐三个Windows远程桌面客户端,mRemote、TSMMC.MSC、Terminals
  5. 开个水果店怎么选址,怎么选水果店选址
  6. 物联网商机惊人 SoC大厂跨界淘金
  7. 我们做新的网站怎么才能让百度蜘蛛快点来爬取收录
  8. iPad Swift Playgrounds中实现AR 3D物体识别
  9. 零代码编程:用ChatGPT将PDF文件的表格批量转为Excel表格
  10. 创始人纷纷“隐退” 互联网大厂竞相开启新阶段