vlambda博客
学习文章列表

Leecode-Go-最大子数组和(切片相关)

给定一个整数数组nums,需要我们找出一个具有最大和的连续子数组(子数组最少包含一个元素),但是只需要返回其最大和,需要注意的是,子数组表示的是数组中的一个连续部分。


举个例子,比如说我们输入的内容是nums = [-2,1,-3,4,-1,2,1,-5,4],那么我们输出的内容就应该是6。


那么我们来详细的分析一下,如下是我们利用滑动窗口算法之后,所有可以找到的子数组,以及聚合之后的结果,将结果对比后可得到上述答案:

  1. 可找到的所有子数组为:[-2] ,求和之后的值为:-2

  2. 可找到的所有子数组为:[1] ,求和之后的值为:1

  3. 可找到的所有子数组为:[-3] ,求和之后的值为:-3

  4. 可找到的所有子数组为:[4] ,求和之后的值为:4

  5. 可找到的所有子数组为:[-1] ,求和之后的值为:-1

  6. 可找到的所有子数组为:[2] ,求和之后的值为:2

  7. 可找到的所有子数组为:[1] ,求和之后的值为:1

  8. 可找到的所有子数组为:[-5] ,求和之后的值为:-5

  9. 可找到的所有子数组为:[4] ,求和之后的值为:4

  10. 可找到的所有子数组为:[-2 1] ,求和之后的值为:-1

  11. 可找到的所有子数组为:[1 -3] ,求和之后的值为:-2

  12. 可找到的所有子数组为:[-3 4] ,求和之后的值为:1

  13. 可找到的所有子数组为:[4 -1] ,求和之后的值为:3

  14. 可找到的所有子数组为:[-1 2] ,求和之后的值为:1

  15. 可找到的所有子数组为:[2 1] ,求和之后的值为:3

  16. 可找到的所有子数组为:[1 -5] ,求和之后的值为:-4

  17. 可找到的所有子数组为:[-5 4] ,求和之后的值为:-1

  18. 可找到的所有子数组为:[-2 1 -3] ,求和之后的值为:-4

  19. 可找到的所有子数组为:[1 -3 4] ,求和之后的值为:2

  20. 可找到的所有子数组为:[-3 4 -1] ,求和之后的值为:0

  21. 可找到的所有子数组为:[4 -1 2] ,求和之后的值为:5

  22. 可找到的所有子数组为:[-1 2 1] ,求和之后的值为:2

  23. 可找到的所有子数组为:[2 1 -5] ,求和之后的值为:-2

  24. 可找到的所有子数组为:[1 -5 4] ,求和之后的值为:0

  25. 可找到的所有子数组为:[-2 1 -3 4] ,求和之后的值为:0

  26. 可找到的所有子数组为:[1 -3 4 -1] ,求和之后的值为:1

  27. 可找到的所有子数组为:[-3 4 -1 2] ,求和之后的值为:2

  28. 可找到的所有子数组为:[4 -1 2 1] ,求和之后的值为:6

  29. 可找到的所有子数组为:[-1 2 1 -5] ,求和之后的值为:-3

  30. 可找到的所有子数组为:[2 1 -5 4] ,求和之后的值为:2

  31. 可找到的所有子数组为:[-2 1 -3 4 -1] ,求和之后的值为:-1

  32. 可找到的所有子数组为:[1 -3 4 -1 2] ,求和之后的值为:3

  33. 可找到的所有子数组为:[-3 4 -1 2 1] ,求和之后的值为:3

  34. 可找到的所有子数组为:[4 -1 2 1 -5] ,求和之后的值为:1

  35. 可找到的所有子数组为:[-1 2 1 -5 4] ,求和之后的值为:1

  36. 可找到的所有子数组为:[-2 1 -3 4 -1 2] ,求和之后的值为:1

  37. 可找到的所有子数组为:[1 -3 4 -1 2 1] ,求和之后的值为:4

  38. 可找到的所有子数组为:[-3 4 -1 2 1 -5] ,求和之后的值为:-2

  39. 可找到的所有子数组为:[4 -1 2 1 -5 4] ,求和之后的值为:5

  40. 可找到的所有子数组为:[-2 1 -3 4 -1 2 1] ,求和之后的值为:2

  41. 可找到的所有子数组为:[1 -3 4 -1 2 1 -5] ,求和之后的值为:-1

  42. 可找到的所有子数组为:[-3 4 -1 2 1 -5 4] ,求和之后的值为:2

  43. 可找到的所有子数组为:[-2 1 -3 4 -1 2 1 -5] ,求和之后的值为:-3

  44. 可找到的所有子数组为:[1 -3 4 -1 2 1 -5 4] ,求和之后的值为:3

  45. 可找到的所有子数组为:[-2 1 -3 4 -1 2 1 -5 4] ,求和之后的值为:1


到这里题意差不多都理解了,之后我们来看下最笨的解决方法:

package main
import "fmt"
func main() { nums := []int{-2, 1, -3, 4, -1, 2, 1, -5, 4} fmt.Println(maxSubArray(nums))}
func maxSubArray(nums []int) int { var ( sign = 1 maxNum = 0 numsLen = len(nums) maxAry = make(map[int]int) )
maxNum = nums[0] for sign <= numsLen { for i := 0; i < numsLen; i++ { if i+sign <= numsLen { sonNum := nums[i] for j := i + 1; j < i+sign; j++ { sonNum += nums[j] } fmt.Println("可找到的所有子数组为:", nums[i:i+sign], ",求和之后的值为:", sonNum) if _, ok := maxAry[sign]; ok { if maxAry[sign] < sonNum { maxAry[sign] = sonNum } } else { maxAry[sign] = sonNum } } }
if maxNum < maxAry[sign] { maxNum = maxAry[sign] }
sign++ }
return maxNum}


上述方法就是我能给出的答案。


但肯定不是最好的,我顺手找了别的方案,希望可以给各位开拓一下思路:

package main
import "fmt"
func main() { nums := []int{-2, 1, -3, 4, -1, 2, 1, -5, 4} fmt.Println(test(nums))}
func test(nums []int) int { numsLen := len(nums) maxNum := nums[0] for i := 1; i < numsLen; i++ { if nums[i-1] > 0 { nums[i] = nums[i] + nums[i-1] }
if maxNum < nums[i] { maxNum = nums[i] } }
return maxNum}


套用人家作者的原话,这种方式或者是思想可以理解为动态规划,nums[i-1]并不是数组前一项的意思,而是到前一项为止的最大子序和,和0比较是因为只要大于0,就可以相加构造最大子序和,如果小于0则相加为0,nums[i]=nums[i],相当于最大子序和又重新计算,本质其实是一边遍历一边计算最大序和。


牛吧,我这种凡人根本没想到。。。


至此,本次分享就结束了,后期会慢慢补充。


以上仅为个人观点,不一定准确,能帮到各位那是最好的。


好啦,到这里本文就结束了,喜欢的话就来个三连击吧。


以上均为个人认知,如有侵权,请联系删除。