本文覆盖了最大连续子序列和以及一些变体题目。
53. 最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
ans = nums[0]
tmp = nums[0]
for i in range(1,len(nums),1):
tmp = max(tmp+nums[i], nums[i])
ans = max(ans, tmp)
return ans
两个不重合的连续子数组最大和
在上题基础上,求解数组的两个不重合的连续子数组和的最大值。
解题思路:
最开始的思路,就是将数组分为两部分,分别求最大连续子数组和然后相加,时间复杂度为O(n^2)。
进一步优化:
1.构建两个dp数组,分别表示从左到右,从右到左的连续子数组和的最大值。
2.遍历不同的划分点,计算最大值。
与上述类似思路的题目 135. 分发糖果
def maxtwo(nums):
n = len(nums)
def leftmax(l):
dp = [0]*n
t = 0
ans = float('-inf')
for i in range(n):
t = max(l[i], l[i]+t)
ans = max(t, ans)
dp[i] = ans
return dp
def rightmax(l):
dp = [0]*n
t = 0
ans = float('-inf')
for i in range(n-1,-1,-1):
t = max(l[i], t+l[i])
ans = max(t, ans)
dp[i] = ans
return dp
left = leftmax(nums)
right = rightmax(nums)
ans = float('-inf')
for i in range(n-1):
ans = max(ans, left[i] + right[i+1])
return ans
面试题 17.24. 最大子矩阵
给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。
面试题 17.24. 最大子矩阵
解题思路:将二维数组转化为一维数组( O ( n 2 ) O(n^2) O(n2)),再利用动态规划思路解题,时间复杂度 O ( n 3 ) O(n^3) O(n3)
class Solution:
def getMaxMatrix(self, matrix: List[List[int]]) -> List[int]:
N,M=len(matrix), len(matrix[0])
r1,r2,c1,c2=0,0,0,0
l = [0]*M
sum1 = float('-inf')
for i in range(N):
for x in range(M):
l[x] = 0
for j in range(i,N):
for k in range(M):
l[k] = l[k] + matrix[j][k]
# 一维数组求最大元素和
t = 0
begin=0
for a in range(M):
if a==0 or t < 0:
t = l[a]
begin = a
else:
t = l[a] + t
if t > sum1:
sum1 = t
r1,r2,c1,c2=i,j,begin,a
return [r1,c1,r2,c2]