Algorithm question: the maximum sum of continuous sub-arrays, analysis process (dynamic programming)

Title description

HZ occasionally uses professional questions to fool those non-computer majors. After the test group had a meeting today, he spoke again: In the ancient one-dimensional pattern recognition, it is often necessary to calculate the maximum sum of continuous sub-vectors. When the vectors are all positive, the problem is solved easily. However, if the vector contains negative numbers, should it contain a certain negative number and expect the positive number next to it to make up for it? For example: {6,-3,-2,7,-15,1,2,2}, the maximum sum of consecutive subvectors is 8 (starting from the 0th and ending with the 3rd). Give an array and return the sum of its largest consecutive subsequences. Will you be fooled by him? (The length of the sub-vector is at least 1)

Topic analysis

Note that the maximum sum of sub-vectors from 0 to i is ans[i], subRight[i] is the maximum sum of all sub-vectors ending with the element marked i, which can be easily obtained, ans[i] = max(ans[ i-1],subRight[i]), because ans[i-1] is calculated from all sub-vectors that do not contain elements of array[i], and subRight[i] is calculated from all sub-vectors that contain elements of array[i] The vector is calculated.

Then the goal of the question is to calculate ans[array.length-1], how to calculate a[i]? Use ans[i] = max(ans[i-1],subRight[i]), then how to calculate subRight[ i], first of all subRight[0] must be array[0], other cases can be drawn like this: if subRight[i-1]>0, add array[i], if subRight[[i-1]< =0, to get the largest one, it is better to form a sub-vector by array[i].

From this, the answer can be obtained in one traversal, and the time complexity is o(n)

Code

 //子向量最大和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;
    }

Guess you like

Origin blog.csdn.net/Baibair/article/details/108564997