解法一:暴力法
func maxSubArray(nums []int) int {
res := math.MinInt32
n := len(nums)
for i := 0;i < n;i++ {
for j := i; j < n; j++ {
count := 0
for k := i; k < j; k++ {
count += nums[k]
}
if count > res {
res = count
}
}
}
return res
}
func maxSubArray(nums []int) int {
res := math.MinInt32
n := len(nums)
for i := 0;i < n;i++ {
count := 0
for j := i; j < n; j++ {
count += nums[j]
if count > res {
res = count
}
}
}
return res
}
解法二:分治
- 取数组中点,最大子序要么在其左侧,要么在其右侧,要么跨越中点,故分为这三种情况
- 左、右 可以继续分治,指导取值范围足够小(小到只有一个值,也就是左右边界相等)即可返回
- 跨越中点,从中点往前,往后分别计算其最大值,然后相加即可。
注:k = log N
func maxSubArray(nums []int) int {
return getMaxSubarray(nums ,0, len(nums) -1)
}
func getMaxSubarray(nums []int, start , end int) int {
if start == end {
return nums[start]
}
mid := start + (end - start) >> 1
leftMax := getMaxSubarray(nums, start, mid)
rightMax := getMaxSubarray(nums, mid + 1, end)
corssMax := getCorssMaxSubarray(nums, start, end, mid)
return max(leftMax, rightMax, corssMax)
}
func getCorssMaxSubarray(nums []int, start, end, mid int) int {
leftSum := math.MinInt32
sum := 0
for i:= mid; i >= start; i-- {
sum += nums[i]
leftSum = max(leftSum, sum)
}
rightSum := math.MinInt32
sum = 0
for i:= mid + 1; i <= end; i++ {
sum += nums[i]
rightSum = max(rightSum, sum)
}
return (leftSum + rightSum)
}
func max (params ...int) int {
res := params[0]
for _, val := range params {
if val > res {
res = val
}
}
return res
}
解法三:贪心
从左到右,如果遇到 sum < 0 ,就归零,继续重新累加
func maxSubArray(nums []int) int {
max := math.MinInt32
sum := 0
for _, val := range nums {
sum += val
if sum > max {
max = sum
}
if sum < 0 {
sum = 0
}
}
return max
}
解法四:DP
func maxSubArray(nums []int) int {
n := len(nums)
dp := make([]int, n)
dp[0] = nums[0]
// 表示以数组第一位结束的最大子序和
res := nums[0]
for i:= 1; i < n ; i++ {
dp[i] = max(dp[i-1]+nums[i], nums[i])
res = max(dp[i], res)
}
return res
}
func max(params ...int) int {
res := math.MinInt32
for _, val := range params {
if val > res {
res = val
}
}
return res
}
状态优化:
func maxSubArray(nums []int) int {
n := len(nums)
dp := nums[0]
// 表示以数组第一位结束的最大子序和
res := nums[0]
for i:= 1; i < n ; i++ {
dp = max(dp+nums[i], nums[i])
res = max(dp, res)
}
return res
}
func max(params ...int) int {
res := math.MinInt32
for _, val := range params {
if val > res {
res = val
}
}
return res
}