Leetcode解题之路(golang版):53. 最大子序和(Maximum Subarray)

53. 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

解不出来法一:

空间复杂度:$O(1)$

时间复杂度:$O(n3)$

//暴力解决问题,但是并不能解决,会超时
//引以为戒
func maxSubArray(nums []int) int {
    if len(nums) == 0 {
        return 0
    }
    if len(nums) == 1 {
        return nums[0]
    }
    max := -0xffffffff
    for i := 0; i < len(nums); i++ {
        
        for j := i; j < len(nums); j++ {
            temp := 0
            for k := i; k <= j; k++ {
                temp += nums[k]
            }
            if temp > max {
                max = temp
            }
        }
    }
    return max
}

解法二:动态规划

空间复杂度:$O(1)$

时间复杂度:$O(n)$

//这里使用max记录最大值
//tmp记录当前值,如果当前值已经小于0,可以直接抛弃
//如果大于0,尝试更新max
func maxSubArray(nums []int) int {
    max := int(^(int(^uint(0) >> 1)))
    //fmt.Printf("(^uint(0) >> 1) =       %d\n", (^uint(0) >> 1))
    //fmt.Printf("int(^uint(0) >> 1)    = %b\n", int(^uint(0) >> 1))
    //fmt.Printf("int(^(int(^uint(0)))) = %b\n", int(^(int(^uint(0) >> 1))))
    //fmt.Printf("int(^(int(^uint(0)))) = %b\n", (^(int(^uint(0) >> 1))))
    //fmt.Printf("(^int(0) >> 1) = %b\n", (^int(0) >> 1))
    //fmt.Printf("int(^int(0) >> 1) = %b\n", int(^int(0) >> 1))
    //fmt.Printf("int(^(int(^int(0) >> 1))) = %b\n", int(^(int(^int(0) >> 1))))
    tmp := 0
    for _, v := range nums {
        if tmp > 0 {
            tmp += v
        } else {
            tmp = v
        }
        if max < tmp {
            max = tmp
        }
        //fmt.Println(tmp)
    }
    return max
}

解法三:分治算法

空间复杂度:$O(1)$

时间复杂度:$O(nlogn)$

//分支算法的主要思路是将数组一份为二
//左边,中间一个,右边
//最大值肯定出现在左边,右边,穿过中间这三者之间
//关于这种算法的时间复杂度我没算太明白,但是有一个博文说的很清楚,把地址贴在算法的下方
func maxPart(nums []int, left int, right int) int {
    if left == right {
        return nums[left]
    }
    if left > right {
        return int(^(int(^uint(0) >> 1)))
    }
    mid := (left + right) >> 1
    maxLeft := maxPart(nums, left, mid - 1)
    maxRight := maxPart(nums, mid + 1, right)
    partLeftMax := 0
    partRightMax := 0
    sum := 0
    for i := mid - 1; i >= left; i-- {
        sum += nums[i]
        if sum > partLeftMax {
            partLeftMax = sum 
        }
    }
    sum = 0
    for i := mid + 1; i <= right; i++ {
        sum += nums[i]
        if sum > partRightMax {
            partRightMax = sum
        }
    }
    partMidMax := partLeftMax + partRightMax + nums[mid]
    tmp := 0
    if maxLeft > maxRight {
        tmp = maxLeft
    } else {
        tmp = maxRight
    }
    if tmp < partMidMax {
        tmp = partMidMax
    }
    //fmt.Printf("left = %d right = %d tmp = %d\n", left, right, tmp)
    return tmp
}

func maxSubArray(nums []int) int {
    return maxPart(nums, 0, len(nums) - 1)
}

算法复杂度分析博文:https://www.cnblogs.com/genialx/p/10178182.html

问题

在这里有一个问题还没解决,max初始值应该设定为一个int类型的最小值

int(^(int(^uint(0) >> 1)))为int最小值
但是为什么int(^(^uint(0) >> 1))就不可以

会提示报错,错误如下:

底层二进制的表示应该都是011111…
不清楚这里问什么不可以,如果有人知道,欢迎留言。

你可能感兴趣的:(leetcode)