多语言展示
当前在线:517今日阅读:26今日分享:39

使用java实现求最大和非空子数组的问题

对于一个数组a,我们需要找到其中连续的几个数使得它们的和最大。最容易想到的方法是尝试每一对起始索引与结束索引,得出它们的和。这样得到的时间复杂度为O(n^2)级别。下面我们设计一种更好的方式来计算,使得时间复杂度可以降为O(n*log n)。
工具/原料
1

jdk

2

idea

方法/步骤
1

我们首先描述这个问题的解决思路。基本的思路是采用分治法:对于一个数组A[low...high],将其从中间分为两个部分a[low...mid]与a[mid+1...high]。这样,任何连续子数组必定属于以下三种情况之一:1.完全位于左侧数组;2.完全位于右侧数组;3.跨越了中间元素的数组。

2

我们可以在线性时间内求出跨越mid位置元素的子数组。从mid位置开始,依次向两侧搜索,可以获得跨越mid位置元素的子数组,返回最终的左侧位置、右侧位置与最大和。

3

然后使用递归找出长度缩小一半的两部分数组的最大子数组,最后返回三者之中的最大值,递归出口为数组只有一个元素。以下为该思路的伪代码。

4

下面我们使用java语言实现以上的算法。首先,由于以上两个函数返回值均为多个值,但数据类型均为整型,因此返回值为List,将返回值完全封装在里面。首先求出mid左侧的最大值,实现方法如下。

6

然后使用递归策略,反复调用该方法,每调用一个,数组的长度减半,直到每一个数组只剩下一个元素时,递归开始回溯。

7

接下来测试以上的算法,使用数组{13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7},测试代码如下。这里使用流操作与Lambda表达式输出子数组。

8

输出结果如下,与实际的最大值相同。

推荐信息