最大子列和问题
2016-01-20 21:56
357 查看
解法1:
直接枚举所有情况暴力求解问题
O (n^3)
解法2:
在解法1的基础上改善了局部求和方法,使用递推和式代替每次累加求和
O (n^2)
解法3:
采用分治法求解,将数列递归地一分为二,最大子列和就等于左边的最大子列和与右边的最大子列和与跨越中线的最大子列和的最大值。
O (n logN)
解法4:
采用在线扫描方法,从起点开始往终点扫描,记录当前的子列和,如果为负数则舍弃之并将当前和置0,并更新现发现的当前最大子列和。
O (n)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#define MAX(a,b) (a)>(b)?(a):(b)
using namespace std;
int a(int *str, int x, int y){// 暴力求解法 array str, [x,y)
if (x == y) //异常处理
return -1;
int max = str[x],curSum;
for (int i = x; i < y; i++){
for (int j = i; j < y; j++){
curSum = 0;
for (int k = i; k <= j; k++){ //calculate the current sum from i to j
curSum += str[k];
}
if (max < curSum){
max = curSum;
}
}
}
return max;
}
int b(int *str, int x, int y){// 暴力求解法的优化
if (x == y) //异常处理
return -1;
int max = str[x], curSum;
for (int i = x; i < y; i++){
curSum = 0; // 和式由递推关系获得
for (int j = i; j < y; j++){
curSum += str[j];
if (max < curSum){
max = curSum;
}
}
}
return max;
}
int c(int *str, int x, int y){<span style="white-space:pre"> </span>// <span style="white-space:pre"> </span>分治法
if (x == y) //异常处理
return -1;
if (y - x == 1) // 如果只有一个元素,则直接返回
return str[x];
int mid = x + (y - x) / 2; //划分成两个子区间
int max = MAX(c(str, x, mid), c(str, mid, y));// 递归求解每个区间的最大子列和
int left, right, curSum, maxLeft = str[mid-1], maxRight = str[mid]; //求解中间部分的最大子列和
for (left = mid-1, curSum = 0; left >= x; left--){
curSum += str[left];
if (curSum > maxLeft){
maxLeft = curSum;
}
}
for (right = mid, curSum = 0; right < y; right++){
curSum += str[right];
if (curSum>maxRight){
maxRight = curSum;
}
}
return MAX(max, maxLeft + maxRight);
}
int d(int *str, int x, int y){ //在线扫描法
if (x == y) //异常处理
return -1;
int curSum =0, max = str[x];
for (int i = x; i < y; i++){
curSum += str[i];
if (curSum>max){
max = curSum; //更新最大和
}
if (curSum < 0){
curSum = 0; //如果为负数则舍弃之并将当前和置0,因为当前子列和为负只能使之后的子列和变小
}
}
return max;
}
int main()
{
int array[] = {4,-3,5,-2,-1,2,6,-2};
cout << "暴力求解 :"<<a(array,0,8)<<endl;
cout << "优化后的暴力求解 :"<<b(array, 0, 8) << endl;
cout << "分治求解 :"<<c(array, 0, 8)<<endl;
cout << "最优的在线处理 :"<<d(array, 0, 8) << endl;
system("pause");
return 0;
}
直接枚举所有情况暴力求解问题
O (n^3)
解法2:
在解法1的基础上改善了局部求和方法,使用递推和式代替每次累加求和
O (n^2)
解法3:
采用分治法求解,将数列递归地一分为二,最大子列和就等于左边的最大子列和与右边的最大子列和与跨越中线的最大子列和的最大值。
O (n logN)
解法4:
采用在线扫描方法,从起点开始往终点扫描,记录当前的子列和,如果为负数则舍弃之并将当前和置0,并更新现发现的当前最大子列和。
O (n)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#define MAX(a,b) (a)>(b)?(a):(b)
using namespace std;
int a(int *str, int x, int y){// 暴力求解法 array str, [x,y)
if (x == y) //异常处理
return -1;
int max = str[x],curSum;
for (int i = x; i < y; i++){
for (int j = i; j < y; j++){
curSum = 0;
for (int k = i; k <= j; k++){ //calculate the current sum from i to j
curSum += str[k];
}
if (max < curSum){
max = curSum;
}
}
}
return max;
}
int b(int *str, int x, int y){// 暴力求解法的优化
if (x == y) //异常处理
return -1;
int max = str[x], curSum;
for (int i = x; i < y; i++){
curSum = 0; // 和式由递推关系获得
for (int j = i; j < y; j++){
curSum += str[j];
if (max < curSum){
max = curSum;
}
}
}
return max;
}
int c(int *str, int x, int y){<span style="white-space:pre"> </span>// <span style="white-space:pre"> </span>分治法
if (x == y) //异常处理
return -1;
if (y - x == 1) // 如果只有一个元素,则直接返回
return str[x];
int mid = x + (y - x) / 2; //划分成两个子区间
int max = MAX(c(str, x, mid), c(str, mid, y));// 递归求解每个区间的最大子列和
int left, right, curSum, maxLeft = str[mid-1], maxRight = str[mid]; //求解中间部分的最大子列和
for (left = mid-1, curSum = 0; left >= x; left--){
curSum += str[left];
if (curSum > maxLeft){
maxLeft = curSum;
}
}
for (right = mid, curSum = 0; right < y; right++){
curSum += str[right];
if (curSum>maxRight){
maxRight = curSum;
}
}
return MAX(max, maxLeft + maxRight);
}
int d(int *str, int x, int y){ //在线扫描法
if (x == y) //异常处理
return -1;
int curSum =0, max = str[x];
for (int i = x; i < y; i++){
curSum += str[i];
if (curSum>max){
max = curSum; //更新最大和
}
if (curSum < 0){
curSum = 0; //如果为负数则舍弃之并将当前和置0,因为当前子列和为负只能使之后的子列和变小
}
}
return max;
}
int main()
{
int array[] = {4,-3,5,-2,-1,2,6,-2};
cout << "暴力求解 :"<<a(array,0,8)<<endl;
cout << "优化后的暴力求解 :"<<b(array, 0, 8) << endl;
cout << "分治求解 :"<<c(array, 0, 8)<<endl;
cout << "最优的在线处理 :"<<d(array, 0, 8) << endl;
system("pause");
return 0;
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C++联合体转换成C#结构的实现方法
- C#实现的算24点游戏算法实例分析
- C++高级程序员成长之路
- C++编写简单的打靶游戏