LeetCode题解10:子数组的最大值

这篇博客介绍了LeetCode的‘最大子数组’问题,包括题目要求和两种解题方法:动态规划与分治法。通过分治法,将数组分为左右两部分,分析三种可能的最大子数组情况,并给出代码实现。同时提到,动态规划法在Java提交中具有更好的时间复杂度表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
题目要求
  1. 给定一个数组,求这个数组的连续子数组中的元素之和的最大值。
解题思路

有两种解决方法:1. 动态规划法 2. 分治法,这篇文章会分别介绍这两种方法并给出代码。

  1. 分治法:将原数组分成左右长度相同的两个子数组。由于是连续子数组,此时最大值只有可能有三种情况,在左边的子数组中,在右边的子数组中,横跨左右子数组;前两种情况可以通过递归求出来,第三种情况对左右子数组进行分析。因为是连续且横跨左右两个子数组,所以所以可以从中间开始分析,分别求出右边的最大连续子数组值和左边的连续子数组值,最后将这两者之和与前两种情况的结果相比较,取最大值。代码如下:

    时间复杂度O(nlog n) 超过77%的java提交

    class Solution {
        public int maxSubArray(int[] nums) {
            int l = 0,r = nums.length;
            return recursive(nums,l,r);
        }
        private int recursive(int[] nums,int l,int r){
            if(l+1==r) return nums[l];
            int middle = (l+r)/2;
            int lval = recursive(nums,l,middle);
            int rval = recursive(nums,middle,r);
            // 合并中间的值
            int lspread=2,rspread=1,maxl = nums[middle-1],maxr=nums[middle];
            int templ=maxl,tempr=maxr;
            while(middle-lspread>=l){
                templ+=nums[middle-lspread];
                maxl = Math.max(maxl,templ);
                lspread++;
            }
            while(middle+rspread<r){
                tempr+=nums[middle+rspread];
                maxr=Math.max(maxr,tempr);
                rspread++;
            }
            return Math.max(maxr+maxl,Math.max(lval,rval));
        }
    }
    
    1. 动态规划法:超过100%的java提交

    时间复杂度O(n)

    class Solution {
        public int maxSubArray(int[] nums) {
            // 核心思想,如果当前计算的和小于0,那么肯定不可能使总的和更大了
            // 所以此时我们重置当前计算的和
            // 然后更新最大和
            int maxsum=nums[0],tempsum = nums[0];
            for(int i = 1;i<nums.length;i++){
                tempsum = tempsum>0?tempsum+nums[i]:nums[i];
                maxsum=maxsum>tempsum?maxsum:tempsum;
            }
            return maxsum;
        }
        
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值