------------------------------------maxsubsum.go------------------------------------------
package maxsubsum // 问题描述:最大子序列和 // 给定(有可能为负的)整数A1A2,...,An,求sum(Ai,...,Aj)最大值(如所有整数均为负数,则最大子序列和为0) // -2,11,-4,13,-5,-2,答案为20(从A2到A4) // 暴力枚举所有情况 时间复杂度 o(n^2) 空间复杂度 o(1) func maxSubSum1(arr []int) (max int) { length := len(arr) for i := 0; i < length; i++ { tmpMax := 0 for j := i; j < length; j++ { tmpMax += arr[j] if tmpMax >= max { max = tmpMax } } } return } // 使用递归 将数组中间拆分,最大值可能出现在左半部分,或者右半部分,或者跨越左右两部分 // 时间复杂度 o(NlogN) 空间复杂度 o(n) func maxSubSum2(arr []int) (max int) { size := len(arr) // 递归出口,子序列没有元素或者只剩一个元素时结束递归 if size < 1 { return } if size == 1 { if arr[0] > 0 { max = arr[0] } return } // 递归计算左右两部分的最大值 center := size / 2 maxSumLeft := maxSubSum2(arr[0:center]) maxSumRight := maxSubSum2(arr[center:]) // 计算可能跨越左右两部分的最大值 // 从中间切分点向左,向右分别计算最大值,二者之和为跨越中点的最大值 var leftMaxSum, leftTempMaxSum int for i := center - 1; i > -1; i-- { leftTempMaxSum += arr[i] if leftMaxSum <= leftTempMaxSum { leftMaxSum = leftTempMaxSum } } var rightMaxSum, rightTempMaxSum int for i := center; i < size; i++ { rightTempMaxSum += arr[i] if rightMaxSum <= rightTempMaxSum { rightMaxSum = rightTempMaxSum } } maxSumCenter := leftMaxSum + rightMaxSum // 从左最大值,右最大值,中间最大值中选择最大值为最终结果 if maxSumLeft > maxSumRight { if maxSumLeft > maxSumCenter { return maxSumLeft } else { return maxSumCenter } } else { if maxSumRight > maxSumCenter { return maxSumRight } else { return maxSumCenter } } } // 优化过的算法 // 从左到右依次扫描求和,如果某值为负数,其不可能为序列的起始,继续判断下一个值;某个子序列的和<0,则该序列不可能为最大和子序列的一部分 // 时间复杂度 o(n 空间复杂度 o(1) func maxSubSum3(arr []int) (max int) { var tmpSum int for _, val := range arr { tmpSum += val if tmpSum > max { max = tmpSum } if tmpSum < 0 { tmpSum = 0 } } return }
--------------------------------------------maxsubsum_test.go-----------------------------------------------
package maxsubsum import ( "testing" "math/rand" "time" "fmt" ) type Data struct { Arr []int Max int } var data = []Data{ {[]int{-2, 11, -4, 13, -5, -2}, 20}, {[]int{4, -3, 5, -2, -1, 2, 6, -2}, 11}, } func TestMaxSubSum(t *testing.T) { for i,f:=range []func([]int)int{maxSubSum1,maxSubSum2,maxSubSum3}{ for _, item := range data { max := f(item.Arr) if max != item.Max { t.Errorf("method %d input %v expect %d but got %d \n", i,item.Arr, item.Max, max) } } } } func TestLargeScale(t *testing.T) { // 生成长度为10万的测试数组 rand.Seed(time.Now().UnixNano()) arr:=make([]int,100000) for i:=0;i<len(arr);i++{ flag :=1 if rand.Intn(3)==1{ flag=-1 } arr[i]=rand.Intn(1000)*flag } for i,f:=range []func([]int)int{maxSubSum1,maxSubSum2,maxSubSum3}{ start:=time.Now().UnixNano() max:=f(arr) end:=time.Now().UnixNano() fmt.Printf("方式%d 计算结果: %d 耗时:%d\n",i,max,end-start) } }