题目描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
链接:https://leetcode-cn.com/problems/maximum-subarray
解题思路1:
依次遍历的方式选出每一子数组中连续的和,然后统一放到列表中,再进行寻找最大值。
number = 1
list = [1,2,3,4,5,6,-1,-4]
for i in range(len(list)):
if i <= len(list)-number:
print(sum(list[i:i+number]), end =' ')
代码1: 超出时间限制
class Solution(object):
def maxSubArray(self, nums):
max_number = []
m = len(nums)
for i in range(m):
for number in range(1, m+1):
if i <= m-number:
max_number.append((sum(nums[i:i+number])))
return max(max_number)
if __name__ == "__main__":
s = Solution()
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(s.maxSubArray(nums))
结果为:6
解题思路2:
首先拿到当前索引位置前面的数据总和,将数据总和放到一个列表里,则最大的连续数组和等于列表中最大的值减去最小的值
代码2:
import sys
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
elif len(nums)==1:
return nums[0]
prefix = []
for index, num in enumerate(nums):
if index==0:
prefix.append(num)
else:
prefix.append(num+prefix[-1])
mmin = 0
ret = 1-sys.maxsize # ret = -oo
for index in range(len(nums)):
ret = max(ret, prefix[index]-mmin)
mmin = min(mmin, prefix[index])
return ret
s = Solution()
list = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(s.maxSubArray(list))
结果为:6
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
vector<int> pre(size, 0);
for (int i=0; i<size; i++){
int item = nums[i];
if (i==0){
pre[i] = item;
}else {
pre[i] = pre[i-1] + item;
}
}
int mmin = 0;
int ret = 1<<31;
for (int j=0; j<size; j++){
int item = pre[j];
ret = max(ret, item-mmin);
mmin = min(mmin, item);
}
return ret;
}
};
解题思路3:
用dp[i]表示以下标为i的元素为结尾的最大子序和,
当i = 0时,dp[0] = nums[0]
当i = 1时,如果要跟前i-1个元素联系起来,就是dp[i-1] + nums[1]
- 如果不连起来,只考虑它自身,就是nums[1]
- 因为题目要求最大,所以dp[1] = max(dp[i-1] + nums[1], nums[1])
…
以此类推,当dp[i-1]为正数的情况下,才有必要连起来,否则还不如nums[i]自己一个数字来的大
代码3:
python写法:
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
dp = [nums[0]]
res = dp[0]
for i in range(1, len(nums)):
dp.append(max(dp[i-1] + nums[i], nums[i]))
if dp[-1] > res:
res = dp[-1]
return res
测试代码:
s = Solution()
list = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(s.maxSubArray(list))
C++写法: f [ i ] = m a x ( f [ i − 1 ] , 0 ) + n u m s [ i ] f[i] = max(f[i-1], 0) + nums[i] f[i]=max(f[i−1],0)+nums[i]
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int res = INT_MIN, last = 0;
for(int i = 0; i < nums.size(); i++){
int now = max(last, 0) + nums[i];
res = max(res, now);
last = now;
}
return res;
}
};
解题思路4: 贪心算法
每一步都选择最佳方案,到最后就是全局最优的方案。
代码4:
class Solution:
def maxSubArray(self, nums) :
n = len(nums)
curr_sum = max_sum = nums[0]
for i in range(1, n):
curr_sum = max(nums[i], curr_sum + nums[i])
max_sum = max(max_sum, curr_sum)
return max_sum
参考链接:
[1]. LeetCode-Python-53. 最大子序和
[2]. python之enumerate函数
[3]. 最大子序和