题目
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
暴力求解法
暴力算法思路简单,不需要过多的思路。
在本题中要求解最大和子数组,最简单的方法就是将所有的子序列写出来然后进行比较,找出最大的那一组。
def maxSubArray(self, nums):
max_sum = nums[0] # 取一个变量存放最大子序列的和
for i in range(0, len(nums)):
for j in range(i, len(nums)):
# 进过这两重循环后将所有的子序列列出来
# 然后取一个变量存放当前这一组序列的和
max_ = 0
# 计算每一组子序列的和
for k in range(i, j + 1):
max_ += nums[k]
# 如果这一组子序列之和大于最大子序列之和,则将其赋予最大子序列和
if max_ > max_sum:
max_sum = max_
# 最后返回最大子序列之和
return max_sum
优化后的代码
def maxSubArray(nums):
if len(nums) == 0:
return nums[0]
max_sum = nums[0]
for i in range(len(nums)):
max_ = 0
for j in range(i, len(nums)):
max_ += nums[j]
if max_ > max_sum:
max_sum = max_
return max_sum
动态规划方法
动态规划解析
-
状态定义:设动态规划列表为dp,dp[i]存放的为以元素nums[i]结尾的连续子数组最大和。
-
转移方程:若是dp[i - 1] < 0,说明dp[i - 1]对于nums[i]产生了负影响,,即dp[i - 1] + nums[i]还不如nums[i]自己大,那么dp[i - 1]就应该被舍弃掉。
即:
当dp[i - 1] > 0时:dp[i] = dp[i - 1] + nums[i]
当dp[i - 1] < 0时:dp[i] = nums[i] -
初始状态:
dp[0] = nums[0],其含义为以nums[0]为结尾的最大子序列和为nums[0]。 -
返回值:返回dp表中最大值,代表着全局最大值
代码实现
def maxSubArray(nums):
if len(nums) == 1:
return nums[0]
dp = [0] * len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
if dp[i - 1] + nums[i] <= nums[i]:
dp[i] = nums[i]
if dp[i - 1] + nums[i] > nums[i]:
dp[i] = dp[i - 1] + nums[i]
return max(dp)
由于dp[i]只与dp[i - 1]和nums[i]有关,与num是[i]之前的值无关,因此可以直接在nums上边进行修改,将nums表当做dp表,代码可以优化成如下。
def maxSdubArray(nums):
if len(nums) == 1:
return nums[0]
for i in range(1, len(nums)):
nums[i] += max(nums[i - 1], 0)
return max[nums]