最大子序列和问题的四种解法以及解析
问题描述
求取数组中最大连续子序列和,例如给定数组为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;
}
最大子序列和问题的四种解法以及解析相关推荐
- 四种解法——求子序列的最大连续子序和(普通解法、求和解法、分治法、O(n)级解法)(面试经典题)
励志用少的代码做高效表达 在这四种解法里,解法一是通法,可以学到规律和知识,做基础之用:解法二在解法一的基础上做改进,锻炼思维:解法三则是大名鼎鼎的分治法,涉及到递归的知识,算是"高效算法设 ...
- 算法-寻找数组中的重复值,四种解法
算法-寻找数组中的重复值 寻找数组中的重复值 寻找数组中的重复值 题目来源于:Leetcode-287.本题归类到简单我无法理解-要满足四个条件需要用很特定的解法,面试中要是用到的话很可能是在给自己挖 ...
- python整数拆分dp算法_整数拆分问题的四种解法【转载】
http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 整数划分问题是 ...
- 奖券数目c语言答案,2015 年蓝桥杯 C 语言 B 组省赛第 1 题: 奖券数目 (四种解法 + 详细分析)...
题目 奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利. 虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码 ...
- 【剑指Offer】剪绳子问题——四种解法
剪绳子问题--四种解法 题目描述: 输入描述: 返回值描述: 示例1: 解题思路: 方法1:暴力递归 方法2:记忆化递归 方法三:动态规划 方法四,数学原理 题目描述: 给你一根长度为n的绳子,请把绳 ...
- 销售额超过公司均值的优秀经销商?SQL比例问题之分组比较的四种解法
分组比较是看起来比较简单,但是写起来比较麻烦的问题,一般就是先进行两个不同分组计数.求和.求均值,然后两个均值作比较,这样就涉及表连接和判断,写的代码量就比其他问题多很多.它与连续问题.排名问题和累加 ...
- 最长公共子序列长度的四种解法
一.题目:求两个字符序列的最长公共字符子序列.给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB, ...
- 八皇后问题详解(四种解法)
所有源码都在github上(https://github.com/seasonyao/eight_queen_question) 如果你去百度百科八皇后这个问题,你会发现人家也是历史上有头有脸的一个问 ...
- 青蛙跳台阶c语言递归函数,青蛙跳台阶问题的四种解法
http://raychase.iteye.com/blog/1337359 题目:一只青蛙一次可以跳1级台阶,也可以跳2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 这道题还被ITEye放在了博 ...
最新文章
- 图解Oracle RMAN备份入门
- Scala基础教程(五):函数、闭包
- 一般屏幕的3D模型是公开的吗?
- (六)docker-compose使用教程
- hadoop综述_Hadoop书籍赠品–综述
- 系统中已安装了vmware,请先卸载干净并重启电脑
- 《HTML5与CSS3实战指南》——2.3 HTML5常见问题
- 安卓ondraw刷新视图_android播放动画时是否会调用被操作的视图的onDraw方法?
- (笔试题)被3和5整除的数的和
- Android应用APP: 基于MobileNet和EfficientNet的图像分类模型_调试运行以及打包Tensorflow官方提供的Image classification demo
- AIX下内存泄漏的监控
- 被final关键字坑了
- linux 卸载theano,centos 安装theano
- Shenyu网关本地打docker镜像包
- vue中transition动画实现淡入淡出
- 穷人的语义处理工具箱之二:语义编辑距离
- U-Boot 图形化配置
- sws_getContext和sws_scale分析
- LittleVGL(LVGL)学习笔记——PC 模拟器的安装和使用(CodeBlocks)
- 《趣味知识博文》小W与小L带你聊天式备考CDA Level Ⅰ(二)
热门文章
- golang 压缩算法 gzip/lz4 对比
- 电脑关机很慢很慢的解决办法(Windows XP)
- S5PV210 Study210开发板刷系统
- 推荐三个Windows远程桌面客户端,mRemote、TSMMC.MSC、Terminals
- 开个水果店怎么选址,怎么选水果店选址
- 物联网商机惊人 SoC大厂跨界淘金
- 我们做新的网站怎么才能让百度蜘蛛快点来爬取收录
- iPad Swift Playgrounds中实现AR 3D物体识别
- 零代码编程:用ChatGPT将PDF文件的表格批量转为Excel表格
- 创始人纷纷“隐退” 互联网大厂竞相开启新阶段