给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
来源:leetcode 第53题 https://leetcode-cn.com/problems/maximum-subarray/
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
首先我们想到的是找到所有子数组的和,并用max记录。这样我们在循环结束之后就能得到最大值。这个方法很容易想到也很容易实现。但是其时间复杂度为O(n^2)。所以我用C#语言放入leetcde之后显示的是“超过时间限制”,但是这个思路是没有问题的,也许其他语言就可以了。
代码如下
public class Solution {
public int MaxSubArray(int[] nums) {
int max=0;
for (int i=0;1<nums.Length;i++)
{
int sum=0;
for(int j=i;j<nums.Length;j++)
{
sum=sum+nums[j];
if (max<sum)
max=sum;
}
}
return max;
}
}
当然,为了通过测试,我还用了另一种方法,遍历一遍,得到最大值。设数组有n个数字。
首先,我们可以认为可以将所以的子数组分成n种,分别是以 nums[0] nums[1]…nums[n-1] 结尾的n种数组。
然后,我们来分析一下。
nums[m]前的数组中的和最大数组和记为max,以nums[m]结尾的数组中最大和记为lastmax。
lastmax会有两种可能。如下
1)lastmax<0, 则以nums[m+1]结尾的数组中,新lastmax=nums[m+1],因为其他以nums[m+1]结尾的数组和都<=nums[m+1]+旧lastmax。
2) lastmax>0,则新的lastmax=旧lastmax+nums[m+1]。这个很容易知道。
然后将max与新的lastmax比较,新的max等于大的那个。
总结来说:lastmax是( 以 nums[0] nums[1]…nums[n-1] 结尾的n种数组 )每一种中的最大和。而max就是将n个最大和中的最大值选出来。
但是由于只遍历了一遍,所以时间复杂度是O(n),实现较快。
代码如下
public class Solution {
public int MaxSubArray(int[] nums) {
int max=nums[0];
int Lastmax=nums[0];
for (int i=1;i<nums.Length;i++)
{
if (Lastmax>0)
{
Lastmax=Lastmax+nums[i];
}
else
{
Lastmax=nums[i];
}
max = Math.Max(Lastmax,max);
}
return max;
}
}