劍指offer面試題31連續子數組的最大和

1、題目描述

  HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同窗。今天測試組開完會後,他又發話了:在古老的一維模式識別中,經常須要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。可是,若是向量中包含負數,是否應該包含某個負數,並指望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。你會不會被他忽悠住?算法

2、解題思路

  求連續子數組的最大和,首先想的到最笨的方法就是暴力解決,兩個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;
    }
}

  最後,還有一種經典的動態規劃算法(跟第二種方法相似),咱們要找到狀態轉移方程:spa

  假設f(j)表示從是s[0]到s[j]最大和,則f(j)=max(s[j],f(j-1)+s[j])。示例代碼以下:code

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;
    }
相關文章
相關標籤/搜索