输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组
- 子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
- 如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
- 该题定义的子数组的最小长度为1,不存在为空的子数组,即不存在[]是某个数组的子数组
- 返回的数组不计入空间复杂度计算
要求:时间复杂度O(n),空间复杂度O(n) 进阶:时间复杂度O(n),空间复杂度O(1)
输入:[1,-2,3,10,-4,7,2,-5]
返回值:[3,10,-4,7,2]
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18,故返回[3,10,-4,7,2]
- dp数组表示以下标i为终点的最大连续子数组和
- 连续的子数组要么加上变得更大,要么它本身就更大
- 状态转移为 dp[i] = max(dp[i−1] + array[i], array[i])
- 同时记录子数组的起始下标,每次更新最大值的时候,顺便更新最终的区间首尾
- 最后根据区间首尾获取子数组
func FindGreatestSumOfSubArray(array []int) []int {
res := make([]int, 0)
dp := make([]int, len(array))
dp[0] = array[0]
var maxSum = dp[0]
var left, right int
var leftRes, rightRes int
for i := 1; i < len(array); i++ {
right++
dp[i] = max(dp[i-1]+array[i], array[i])
if dp[i-1]+array[i] < array[i] {
// 当前值比和前边最大加起来都大了,那这就是新边界
left = right
}
if dp[i] > maxSum || dp[i] == maxSum && (right-left+1) > (rightRes-leftRes+1) {
// 和更大或者和一样数组更长
maxSum = dp[i]
leftRes = left
rightRes = right
}
}
for i := leftRes; i <= rightRes; i++ {
res = append(res, array[i])
}
return res
}
func max(x, y int) int {
if x > y {
return x
}
return y
}