アルゴリズムの質問:連続サブアレイの最大合計、分析プロセス(動的計画法)

タイトル説明

HZは、専門的な質問を使用して、コンピュータ以外のメジャーをだます場合があります。今日、テストグループで会議があった後、彼は再び話しました:古代の1次元パターン認識では、連続するサブベクトルの最大合計を計算する必要があることがよくあります。ベクトルがすべて正であれば、問題は簡単に解決されます。しかし、ベクトルに負の数が含まれている場合、それは特定の負の数を含み、その隣の正の数がそれを補うことを期待する必要がありますか?例:{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]でなければなりませんが、他の場合は次のように描画できます:if subRight [i-1]> 0、add array [i]、if subRight [[i-1] < = 0、最大のものを取得するには、array [i]でサブベクトルを形成する方が良いです。

したがって、1つのトラバーサルで答えを得ることができ、時間の複雑さは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;
    }

おすすめ

転載: blog.csdn.net/Baibair/article/details/108564997