问题
给定一整数数组,求连续的子数组和的最大值,例如:
1, -2, 3, 5, -3, 2 最大值为8
0, -2, 3, 5, -1, 2 最大值为9
分析
《编程之美》中给出的算法很精炼,然而解释却比较复杂,如果从“分级组合”的角度去理解要方便很多。
解法
设置两个整数变量:cur 和sum,从给定数组中依次取出所有元素,加到cur 上去,当cur<0 时候重置cur。sum 记录cur 出现过的最大值:
var cur = array[0];
var sum = cur;
for (int i = 1; i < array.Length; i++)
{
cur = cur < 0 ? array[ i ] : cur + array[ i ];
if (sum < cur) sum = cur;
}
return sum;
扩展问题二解法
如果要求得到最大和的连续子数组的起始位置,那么通过以上思路就更加容易写出代码:
int start1 = 0, start2 = 0, end = 0;
var cur = array[0];
var sum = cur;
for (int i = 1; i < array.Length; i++)
{
if (cur < 0)
{
cur = array[ i ];
start2 = i;
}
else cur += array[ i ];
if (sum < cur)
{
sum = cur;
end = i;
start1 = start2;
}
}
//返回 [start1, end]
本例中,我们用start1,start2 来记录起始位置,end 来记录终止位置。start2 相当于“工作变量”,start1 保存历史最大和连续子数组的起始位置。
扩展问题一解法
如果给定的是数组是首尾相连的循环数组,如何求解?首先设计一个函数,求解给定数组中,从from 开始的,最多到to 结束的最大和连续子数组的末尾位置,思路和前面解法类似。
int MaxSum_Position(int[] array, int from, int to)
{
int step = Math.Sign(to - from);
int end = from;
var cur = array[from];
var sum = cur;
for (int i = from + step; i != to + step; i += step)
{
cur += array[ i ];
if (sum < cur)
{
sum = cur;
end = i;
}
}
return end;
}
有了这个函数以后,可以将循环数组中的问题分成两种情况:一种是连续子数组跨越了0 位置的,一种是没有跨越的:
int sum1 = MaxSum(array);//不跨越0 位置的最大和
int i = MaxSum_Position(array, 0, array.Length - 1);
int j = MaxSum_Position(array, array.Length - 1, 0);
int sum2 = 0;
if (i > j) j = i + 1;
for (int k = 0; k < array.Length; k++)
{
sum2 += array[ k ];
if (k == i) k = j - 1; //跳过中间空缺部分
}
return Math.Max(sum1, sum2);
分享到:
相关推荐
初始化⼆维数组 当同时在C语⾔编程中声明和初始化⼀维数组时,不需要指定数组的⼤⼩。 但是这不适⽤于⼆维数组。必须⾄少定义数组的第⼆个维度。⼆ 维数组的元素数量总是等于:⾏数 * 列数 。 将⼆维数组映射到⼀维...
这是我用c语言写的程序,我的其他资源都是免费的,是对于c语言初学者的帮助比较大的,其中有数据结构,window编程。我也在学c语言,每当我写完一个程序,我都会免费发上来。
C语言编程技术实践 源程序(地址法求数组中最大值).docx 学习资料 复习资料 教学资源
c语言中找出一个整型数组中的元素的最大值。源码
编程之美,微软技术面试心得,适合需要面试的同学
关于连续子数组最大和这个问题,有两种解法,一种是动态规划 解法如下: function getMaxSubSum($arr){ $curSum = $arr[0]; $maxSum = $arr[0]; for($i = 1; $i < count($arr); $i++){ if
《Python编程之美——带你进入Python语言世界》课程设计大纲参考.pdf
我编程,我快乐——程序员职业规划之道我编程,我快乐——程序员职业规划之道我编程,我快乐——程序员职业规划之道我编程,我快乐——程序员职业规划之道
1. 编写一个程序打印数出有10个元素的浮点数组a1中最大值和最小值。 2.将有10个元素的数组a1 拷贝至含有15个元素的数组b1的一段位置。 3.将一个已存入数组中的值45,89,7,6,0,按0,6,7,89,45的次序打印...
题目: 编程实现找出一组数的最大值和次大值 要求: 用二分法的策略实现; (2)写出实验报告。 一、 需求分析: 1、输入要输入数组元素的个数,为数组分配存储空间(动态数组); 2、输入数组元素; 3、利用二分法...
net游戏编程源入门经典——C#篇 文档和代码
PHP编程之高级技巧——利用Mysql函数
Linux系统字符终端界面的编程(1)——CURSES库简介.pdf
C语言项目——网络通信编程.zip C语言项目——网络通信编程.zip C语言项目——网络通信编程.zip C语言项目——网络通信编程.zip C语言项目——网络通信编程.zip C语言项目——网络通信编程.zip C语言项目——网络...
java8函数式编程(csdn)————程序
1. 编写一个程序打印数出有10个元素的浮点数组a1中最大值和最小值。 2.将有10个元素的数组a1 拷贝至含有15个元素的数组b1的一段位置。 3.将一个已存入数组中的值45,89,7,6,0,按0,6,7,89,45的次序打印...
希望更多的人能和我一样,把本狂想曲系列中的任何一道面试题当做一道简单的编程题或一个实质性的问题来看待,在阅读本狂想曲系列的过程中,希望你能尽量暂时放下所有有关面试的一切包袱,潜心攻克每一道“编程题”,...
C语言笔记——数组
java代码-定义一个一维数组,求出数组的最大值,最小值,平均值
WPF编程宝典——使用C# 2012和.NET 4.5(第4版)源码,内含32个程序源码文件。