题目描述: 给你一个整数数组 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
方法一:分治法(递归)
class Solution {
/**
* 过渡方法
* @param nums 原数组
* @return 返回最大子段和
*/
public static int maxSubArray(int[] nums) {
return MaxSubArray(nums,0,nums.length-1);
}
/**
* 求最大子段和
* @param nums 待求数组
* @param left 左指针
* @param right 右指针
* @return 最大子段和
*/
public static int MaxSubArray(int[] nums,int left,int right) {
int res=0,leftsum,rightsum,midsum,center;
int sum1,sum2,leftsum1,rightsum1;
if(left==right){ //递归结束条件
res=nums[left]; //递归直至子段只剩一个元素,则最大子段和即为该元素
}else{
center=(left+right)/2; //取中间元素将数组分为两段,分而治之
leftsum=MaxSubArray(nums,left,center);//递归求左边的最大子段和
rightsum=MaxSubArray(nums,center+1,right);//递归求右边的最大子段和
sum1=-1230000000;leftsum1=0;//假设sum1为一个很小的数,求左最大子段和
for (int i = center; i >=left ; i--) {
leftsum1+=nums[i];
if(leftsum1>sum1)sum1=leftsum1;
}
sum2=-1230000000;rightsum1=0;//假设sum2为一个很小的数,求右最大子段和
for (int i = center+1; i <=right ; i++) {
rightsum1+=nums[i];
if(rightsum1>sum2)sum2=rightsum1;
}
midsum=sum1+sum2;
int s;
if(leftsum>rightsum)s=leftsum;
else s=rightsum;
if(s>midsum)res=s;
else res=midsum;
}
return res;
}
}
方法二、动态规划