最大子数组和(53)力扣

题目描述

给你一个整数数组 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值