题解
思路
代码
class Solution:
### 1124 动态规划(64 ms,19.7 MB)
def maxSubArray(self, nums: List[int]) -> int:
dp = [0] * len(nums) # dp[i] 表示以元素 nums[i] 为结尾的连续子数组最大和
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(dp[i-1]+nums[i], nums[i]) # 前一个子数组总和dp[i-1]+当前元素nums[i] 与 当前元素nums[i] 谁更大
return max(dp) # 返回数组中的最大值
### 1124 双循环辅助变量(72 ms,17.1 MB)
def maxSubArray(self, nums: List[int]) -> int:
pre, res = 0, nums[0] # 定义第一个循环变量pre,保存最大值的变量res
for cur in nums: # 定义第二个循环变量cur
cur += max(pre, 0) # 若从头到pre的子数组的总和pre > 0 则加上cur,否则只取cur(当前这个nums[i]的正负性未知)(max取0表示直接去掉之前为负贡献的子数组)
pre = cur # pre所代表的子数组长度加一,则加上cur更新
res = max(res, cur) # 若cur为正,则res增大且更新
return res
### 1124 数组原地变换(76 ms,17.9 MB)
def maxSubArray(self, nums: List[int]) -> int:
for i in range(1, len(nums)):
# nums[i] = 从头到pre的子数组的总和nums[i-1] + nums[i](但当前这个nums[i]的正负性未知)(max取0表示直接去掉之前为负贡献的子数组)
nums[i] += max(nums[i-1], 0)
return max(nums) # 返回数组中的最大值
- 返回和最大的连续子数组
def maxSubArray(nums) -> int:
pre, res = 0, nums[0] # 定义第一个循环变量pre,保存最大值的变量res
start = end = 0
tmp = 0
for i, cur in enumerate(nums): # 定义第二个循环变量cur
if pre < 0:
tmp = 0
start = i
else:
tmp = pre
cur += tmp # 若从头到pre的子数组的总和pre > 0 则加上cur,否则只取cur(当前这个nums[i]的正负性未知)(max取0表示直接去掉之前为负贡献的子数组)
pre = cur # pre所代表的子数组长度加一,则加上cur更新
if res < cur:
res = cur
end = i
# print(start, end)
return res, nums[start: end+1] if start <= end else [nums[start]]
918. 环形子数组的最大和
class Solution:
def maxSubarraySumCircular(self, nums: List[int]) -> int:
n = len(nums)
# 考虑无环情况:最大和子数组不包含首尾元素,只需考虑中间为最大即可
max_ = float('-inf')
pre = 0
for i in range(n):
pre = max(0, pre) + nums[i]
max_ = max(max_, pre)
# 如果最子数组和小于0,说明数组中全为负数,返回最大负数即可
if max_ < 0:
return max_
# 考虑有环情况:最大和子数组包含首尾元素,只需考虑中间为最小即可(即两边最大)
pre = 0
min_ = float('inf')
for i in range(n):
pre = min(0, pre) + nums[i]
min_ = min(min_, pre)
# 比较有环、无环哪种情况的子数组和更大
# 有环状态下,要使得两端之和最大,必须让中间的子数组最小,即最后有环情况下的最大子数组和为sum(nums)-min_
return max(max_, sum(nums) - min_)