题目描述
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。
暴力法(时间复杂度为O(N^2),空间复杂度为O(1))
java实现
class Solution {
public int maxSubArray(int[] nums) {
int result=Integer.MIN_VALUE;
for(int i=0;i<nums.length;i++)
{
int temp=0;
for(int j=i;j<nums.length;j++)
{
temp=temp+nums[j];
result=Math.max(result,temp);
}
}
return result;
}
}
Python实现
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
result=float('-inf')
for i in range(0,len(nums)):
temp=0
for j in range(i,len(nums)):
temp=temp+nums[j]
result=max(result,temp)
return result
分治法(时间复杂度为O(N),空间复杂度为O(logN))
java实现
class Solution {
public int maxSubArray(int[] nums) {
return getMax(nums,0,nums.length-1);
}
private int getMax(int[] nums,int l, int r)
{
if(l==r)
{return nums[l];}
int mid=l+(r-l)/2;
int leftSum=getMax(nums,l,mid);
int rightSum=getMax(nums,mid+1,r);
int crossSum=crossSum(nums,l,r);
return Math.max(crossSum,Math.max(leftSum,rightSum));
}
private int crossSum(int[] nums,int l, int r)
{
int mid=l+(r-l)/2;
//from mid to leftmost
int leftSum=nums[mid];
int leftMax=leftSum;
for(int i=mid-1;i>=l;i--)
{
leftSum+=nums[i];
leftMax=Math.max(leftMax,leftSum);
}
//from mid+1 to rightmost
int rightSum=nums[mid+1];
int rightMax=rightSum;
for(int i=mid+2;i<=r;i++)
{
rightSum+=nums[i];
rightMax=Math.max(rightMax,rightSum);
}
return leftMax+rightMax;
}
}
Python实现
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
return self.getMax(nums,0,len(nums)-1)
def getMax(self,nums,l,r):
if l==r:
return nums[l]
mid=l+(r-l)//2
leftSum=self.getMax(nums,l,mid)
rightSum=self.getMax(nums,mid+1,r)
crossSum=self.crossSum(nums,l,r)
return max(leftSum,rightSum,crossSum)
def crossSum(self,nums,l,r):
mid=l+(r-l)//2
#from mid to leftmost
leftSum=nums[mid]
leftMax=leftSum
for i in range(mid-1,l-1,-1):
leftSum+=nums[i]
leftMax=max(leftMax,leftSum)
#from mid to rightmost
rightSum=nums[mid+1]
rightMax=rightSum
for i in range(mid+2,r+1):
rightSum+=nums[i]
rightMax=max(rightMax,rightSum)
return leftMax+rightMax
动态规划(时间复杂度为O(N),空间复杂度为O(N))
java实现
class Solution {
public int maxSubArray(int[] nums) {
int[] dp=new int[nums.length];
dp[0]=nums[0];
int result=dp[0];
for(int i=1;i<nums.length;i++)
{
dp[i]=Math.max(dp[i-1]+nums[i],nums[i]);
result=Math.max(dp[i],result);
}
return result;
}
}
Python实现
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
dp=[0]*len(nums)
dp[0]=nums[0]
result=nums[0]
for i in range(1,len(nums)):
dp[i]=max(dp[i-1]+nums[i],nums[i])
result=max(result,dp[i])
return result