所谓最大子数组就是连续的若干数组元素,如果其和是最大的,那么这个子数组就称为该数组的最大子数组。最大子数组是很多问题的抽象,比如购买股票。如果把相邻两天的股价之差作为数组元素,那么求在连续的某个时间段内买入股票的最佳时间和卖出股票的最佳时间就可以抽象为计算最大子数组的问题。
时间复杂度为 n 的解法如下:
package main
import (
"fmt"
"math"
)
// 查找数组里最大的数
func findMax(arr []int) (max, index int) {
max = math.MinInt32
index = -1
for i, v := range arr {
if v > max {
max = v
index = i
}
}
return
}
func MaxSubArray(arr []int) (maxSum int, subArr []int) {
// 判空检查
if len(arr) == 0 {
return
}
// 按包含正数方式求最大子数组
maxSum, begin, end, sum := 0, 0, 0, 0
for i, v := range arr {
sum += v
if sum <= 0 {
sum = 0
begin = i + 1
}
if sum > maxSum {
maxSum = sum
end = i
}
}
// 如果全为非正数时,返回最大的数
if maxSum == 0 {
max, index := findMax(arr)
maxSum = max
begin = index
end = index
}
return maxSum, arr[begin : end+1]
}
func main() {
arr := []int{13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}
maxSum, subArr := MaxSubArray(arr)
fmt.Println(maxSum)
fmt.Println(subArr)
}