算法题:连续子数组的最大和,分析过程(动态规划)

通过动态规划算法解决一维模式识别中的连续子数组最大和问题,当数组包含正负数时,需要判断是否包含负数。分析表明,可以使用公式ans[i] = max(ans[i-1], subRight[i])来计算,其中subRight[i]表示以i为结尾的最大子向量和。一次遍历数组即可得到最终最大连续子序列和,时间复杂度为O(n)。" 7740668,458106,ThinkPHP 3.0连接Oracle数据库实战指南,"['数据库', 'Oracle', 'PHP', 'IDE', 'ThinkPHP框架']
摘要由CSDN通过智能技术生成

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

题目分析

记下标0到i的子向量最大和为ans[i],subRight[i]为以下标为i的元素结尾的所有子向量最大和,可以很容易得到,ans[i] = max(ans[i-1],subRight[i]),因为ans[i-1]由所有不包含array[i]的元素的子向量计算得出,subRight[i]由所有包含array[i]的元素的子向量计算得出。

那么题目的目标就是算出ans[array.length-1],怎么算a[i]?利用ans[i] = max(ans[i-1],subRight[i])即可,那么怎么算出subRight[i],首先subRight[0]一定是array[0],其他情况可以这样得出:如果subRight[i-1]>0,加上array[i]就可以,如果subRight[[i-1]<=0, 要得到最大的,还不如array[i]自己一个组成一个子向量。

由此可以在一次遍历得出答案,时间复杂度o(n)

代码实现

 //子向量最大和ans[i]可以由Max(ans[i-1],以array[i]结尾的所有子向量最大和) 计算得出
    public int FindGreatestSumOfSubArray(int[] array) {
        if(array == null){
            return 0;
        }
        int[] subRight = new int[array.length]; //这个数组的意义是 subRight[i] 为以array[i]结尾的所以子向量的最大和
        for (int i = 0; i < subRight.length; i++) {
            subRight[i] = 0; //初始化
        }
        int ans = Integer.MIN_VALUE;
        for (int i = 0; i < array.length; i++) {
            if(i == 0) //一开始先用array[0] 作为subRight[0]
                subRight[i] = array[i];
            else
                subRight[i] = subRight[i-1]>0?subRight[i-1]+array[i]:array[i]; //不是开始,如果以左边元素结尾的子向量最大和大于0
                                                                               // 则用左边结尾的子向量最大和加当前的值作为这里结尾的最大子向量最大和
                                                                               //否则自己一个元素作为一个子向量
            ans = Math.max(ans,subRight[i]); //与上一次得到的ans比较,相当于ans[i] = max(ans[i-1],subRight[i])
        }
        return ans;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值