龙空技术网

LeetCode基础算法题第175篇:求最大子数组的和

吾是我师 650

前言:

现在同学们对“子数组最大和算法分析”大体比较珍视,各位老铁们都想要了解一些“子数组最大和算法分析”的相关知识。那么小编同时在网摘上汇集了一些有关“子数组最大和算法分析””的相关内容,希望我们能喜欢,同学们一起来学习一下吧!



技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后到中级难度,最后到hard难度全部完。目前我选择C语言,Python和Java作为实现语言,因为这三种语言还是比较典型的。由于篇幅和精力有限,其他语言的实现有兴趣的朋友请自己尝试。

如果有任何问题可以在文章后评论或者私信给我。

如果有朋友希望我讲些其他话题,请在评论区留言或者私信给我。

持续分享,敬请关注。



LeetCode 53. 最大子数组的和(Maximum Subarray)

问题描述:

给定一个整数数组nums,找到具有最大和的连续子数组(至少包含一个数字)并返回其和。

注:

如果您已经找到了O(n)解决方案,请尝试使用分而治之的方法方法进行编码,这种方法更加微妙。

示例:C语言实现:

这是一个优化问题,直观看起来很难找出确切的答案。我们来分析一下。

全局最优解就是所有的局部最优解中最大的那个。

局部最优解如何获得?

因为题目说的是"连续子数组",说明了有序性。即查找是有序的。

我们可以从左向右,或者从右向左,或者同时从左右向中间查找。如果我们从左向右查找,我们定义一个变量t用于保存子数组的和,按照要求,t在某一时刻总会有如下特点:

如果t和下一个元素i的和比t大,那么t+i一定比原来的t更有资格成为局部最优解;反之,如果t+i<=t,那么t一定比t+i更有资格成为局部最优解;

如果将t初始化为0,那么通过对nums的遍历,就会出现len(nums) 个不同的局部最优解t,那么其中最大的那个就是我们要的最优解。

最终代码如下:

这种算法应该算作动态规划的解法。代码简单而且高效。但是题目的提供者,却要求用分治法的方法来解。其实分治法的实现要比上面的方法要复杂一些。

分治法要求对问题进一步细分成子问题,然后各个击破再合并成原问题的解。

要注意的是,分治法分解的子问题,可能不是一个单纯问题,可能是一个问题集合。

比如这道题,如果用分治法,它的子问题集合是:

解可能在当前子数组的左半边;解可能在当前子数组的右半边;解可能在左半边的尾部和右半边的前部;

算法要同时考虑这三种情况,因为在整个计算过程,这三种情况可能都会出现。

说实话我没觉得分治法的实现有什么微妙的地方,所以具体实现就不提供了,感兴趣的读者可以自行完成。

Java语言实现:

Java 的实现和C语言的实现一致,不再撰述。

代码如下:

Python语言实现:

Python 的实现和C语言的实现一致,不再撰述。

代码如下:

标签: #子数组最大和算法分析