剑指offer面试题31连续子数组的最大和

一、题目描述

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

二、解题思路

  求连续子数组的最大和,首先想的到最笨的方法就是暴力解决,两个for循环,遍历数组找到和最大的子数组。示例代码:

复制代码
/*
 * 连续子数组的最大和
 */
public class Solution_31
{
    public static void main(String[] args)
    {
        System.out.println(FindGreatestSumOfSubArray(new int[]{ -2, -8, -1, -5, -9 }));
    }
    public static int FindGreatestSumOfSubArray(int[] array)
    {
        if(array==null||array.length<=0)
            return 0;
        int maxSumOfSubArray = Integer.MIN_VALUE;
        for (int i = 0; i < array.length; i++)
        {
            int sum = array[i];
            if (sum > maxSumOfSubArray)
            {
                maxSumOfSubArray = sum;
            }
            for (int j = i + 1; j < array.length; j++)
            {
                if (sum + array[j] > maxSumOfSubArray)
                {
                    maxSumOfSubArray = sum + array[j];
                }
                sum = sum + array[j];
            }
        }
        return maxSumOfSubArray;
    }
}
复制代码

  还有一种方法是,扫描一遍数组,并设置一个变量,保存已经扫描过的sum值,每扫描一个数,如果sum<0,则加上这个数后一定比当前这个数小,所以让sum等于当前这个数,如果sum>=0,则让sum=sum+当前这个数。扫描的过程还有比较Max和sum的值,取较大值。示例代码如下:

复制代码
public class Solution 
{
    public int FindGreatestSumOfSubArray(int[] array)
   {
     if(array==null||array.length<=0)
            return 0;
        int sum = array[0];
        int maxSumOfSubArray = sum;
        for (int i = 1; i < array.length; i++)
        {
            if (sum >=0)
            {
                sum=sum+array[i];
            }
            else
                sum=array[i];
            if(sum>maxSumOfSubArray)
                maxSumOfSubArray=sum;
        }
        return maxSumOfSubArray;
    }
}
复制代码

  最后,还有一种经典的动态规划算法(跟第二种方法类似),我们要找到状态转移方程:

  假设f(j)表示从是s[0]到s[j]最大和,则f(j)=max(s[j],f(j-1)+s[j])。示例代码如下:

复制代码
public static int FindGreatestSumOfSubArray3(int[] array)
    {
        if(array==null||array.length<=0)
            return 0;
        int maxSumOfSubArray = Integer.MIN_VALUE;
        int sum=0;
        for (int i = 0; i < array.length; i++)
        {
            sum=Math.max(array[i], array[i]+sum);
            maxSumOfSubArray=Math.max(maxSumOfSubArray,sum);
        }
        return maxSumOfSubArray;
    }
复制代码

 

posted @   温布利往事  阅读(839)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
历史上的今天:
2015-07-05 Eclipse删除代码中所有注释及空格
点击右上角即可分享
微信分享提示