@@ -18,29 +18,75 @@ If you have figured out the O(*n*) solution, try coding another solution using t
1818
1919** Tags:** Array, Divide and Conquer, Dynamic Programming
2020
21+ ## 题意
22+ > 给定一个整数数组 ` nums ` ,找到` 和 ` 最大的连续子序列(至少包含一个数字),返回该子序列的和
2123
2224## 题解
2325### 思路1
24- > 普通DP 找到公式就好了
25- ``` $xslt
26- 如果nums[0]>=0,则sum = sum + nums[1]
27- 如果nums[0]<0,则sum = nums[1],
28- ```
26+ > (动态规划) O(n)
27+
28+ - 1.设 dp(i)dp(i) 表示以第` i ` y个数字为结尾的最大连续子序列的` 和 ` 是多少。
29+ - 2.初始化 dp(0)=nums[ 0] dp(0)=nums[ 0] 。
30+ - 3.转移方程 dp(i)=max(dp(i−1)+nums[ i] ,nums[ i] )dp(i)=max(dp(i−1)+nums[ i] ,nums[ i] )。可以理解为当前有两种决策,一种是将第` i ` 个数字和前边的数字拼接起来;另一种是第` i ` 个数字单独作为一个新的子序列的开始。
31+ - 4.最终答案为ans=max(dp(k)),0≤k<n。
32+
33+ > 时间复杂度
34+ - 状态数为 O(n),决策数为 O(1),故总时间复杂度为 O(n)。
2935
3036``` go
3137func maxSubArray (nums []int ) int {
3238 dp , ans := make ([]int , len (nums)), nums[0 ]
3339 dp[0 ] = nums[0 ]
3440
3541 for i := 1 ; i < len (nums); i++ {
36- dp[i] = Max (nums[i], nums[i]+dp[i-1 ])
37- ans = Max (ans, dp[i])
42+ dp[i] = max (nums[i], nums[i]+dp[i-1 ])
43+ ans = max ( dp[i], ans )
3844 }
39-
4045 return ans
4146}
4247```
4348### 思路2
49+ > (分治) O(nlogn)
50+
51+ - 考虑区间 ` [l, r] ` 内的答案如何计算,令 ` mid = (l + r) / 2 ` ,则该区间的答案由三部分取最大值,分别是:
52+ - (1). 区间 ` [l, mid] ` 内的答案(递归计算)。
53+ - (2). 区间 ` [mid + 1, r] ` 内的答案(递归计算)。
54+ - (3). 跨越 mid和mid+1 的连续子序列。
55+ - 其中,第(3)部分只需要从 ` mid ` 开始向 ` l ` 找连续的最大值,以及从 ` mid+1 ` 开始向 ` r ` 找最大值即可,在线性时间内可以完成。
56+ - 递归终止条件显然是 l==r ,此时直接返回` nums[l] ` 。
57+
58+ > 时间复杂度
59+
60+ - 由递归主定理 S(n)=2S(n/2)+O(n),解出总时间复杂度为 O(nlogn)。
61+ - 或者每一层时间复杂度是 O(n),总共有 O(logn) 层,故总时间复杂度是 O(nlogn)。
62+
63+ > Code
64+ ``` go
65+ func maxSubArray (nums []int ) int {
66+ return calc (0 , len (nums)-1 , nums)
67+ }
68+
69+ func calc (l , r int , nums []int ) int {
70+ if l == r {
71+ return nums[l]
72+ }
73+ mid := (l + r) >> 1
74+ lmax , lsum , rmax , rsum := nums[mid], 0 , nums[mid+1 ], 0
75+
76+ for i := mid; i >= 1 ; i-- {
77+ lsum += nums[i]
78+ lmax = max (lmax, lsum)
79+ }
80+
81+ for i := mid + 1 ; i <= r; i++ {
82+ rsum += nums[i]
83+ rmax = max (rmax, rsum)
84+ }
85+
86+ return max (max (calc (l, mid, nums), calc (mid+1 , r, nums)), lmax+rmax)
87+ }
88+
89+ ```
4490
4591
4692## 结语
0 commit comments