42. 连续子数组的最大和
问题:输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
解题思路:
1.本来我想的是用二维数组的动态规划方法:用s[i][j]表示从第i个元素到第j个元素之间的所有子数组的和的最大值
我在初始化二维数组s的时候遇到了一些麻烦,我初始化的方法如下:
s = [[0]*length]*length,其中length是输入的整形数组的长度,经过一番调试发现这种初始化二位数组存在问题,经过上网搜查一番https://blog.csdn.net/qq_1290259791/article/details/81009164,发现了问题所在:
a = [[]]*3
a[0].append(1)
a[1].append(2)
a[2].append(3)
print(a)
输出为[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
原因是创建一个列表,然后复制三个,相当于二维数组中,引用的是同一个一位数组。意思就是:a = [[b]]*3只是创建了3个指向b的应用,所以一旦b改变,a中的3个列表也会改变。
生成方法更改为:
b = [[] for i in range(3)]
b[0].append(1)
b[1].append(2)
b[2].append(3)
print(b)
输出为[[1], [2], [3]]
可以查看列表的id就知道了:
a = [[]]*3
a[0].append(1)
a[1].append(2)
a[2].append(3)
print(id(a[0]))
print(id(a[1]))
print(a)
输出为:
4489350984
4489350984
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
b = [[] for i in range(3)]
b[0].append(1)
b[1].append(2)
b[2].append(3)
print(id(b[0]))
print(id(b[1]))
print(b)
输出为:
4489370184
4489370056
[[1], [2], [3]]
经过修改后我的代码如下(但是不能解决本问题,因为不能确保是连续的子数组):
class Solution:#该方法不能确保是连续的子数组!
def maxSubArray(self, nums: List[int]) -> int:
length = len(nums)
s = [[0] * length for _ in range(length)]
for i in range(length):
s[i][i] = nums[i]
for i in range(length-2,-1,-1):
for j in range(i+1,length):
s[i][j] = max((nums[i]+s[i+1][j]),(s[i][j-1]+nums[j]),s[i+1][j],s[i][j-1])
return s[0][length-1]
该问题只需要一位数组的动态规划方法即可解决:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
dp = len(nums)*[0]
dp[0]=nums[0]
for i in range(1,len(nums)):
dp[i]=max(nums[i],dp[i-1]+nums[i])
return max(dp)
拓展:如果要求 时间复杂度为O(n),空间复杂度为O(1) 【美团面试】
#思路:扫一遍所有数字,同时记录当前的累加和sum_,如果累加和小于0了就置回0,如果累加和比当前记录的最大结果max_sub要大就更新max_sub。
def maxsumofSubarray(arr):
max_sub = 0
sum_ = 0
for i in range(len(arr)):
sum_ += arr[i]
if sum_ < 0:
sum_ = 0
else:
max_sub = max(max_sub,sum_)
return max_sub