Maximum Subarray III

Given an array of integers and a numberk, find knon-overlappingsubarrays which have the largest sum.

The number in each subarray should becontiguous.

Return the largest sum.

Example

Given[-1,4,-2,3,-2,3],k=2, return8

分析:

动归问题。dp[i][j]表示从前i个数( i.e., [0, i-1]) 中取j个subarray得到的最大值,那么要求的结果就是dp[n][k]:从前n个数中取k个subarray得到的最大和。

状态转移:从前i个中取j个,那么我们可以从前p个数(i.e., [0, p-1])中取j-1个subarray,再加上从P到i-1这个subarray中的最大和(也就是Maximum Subarray问题)。从这句话里我们也可以读出来p的范围应该是j-1~i-1

d[i][j] = max{d[i][j],d[p][j-1]+maxSubArray(p+1,i)}

    public int maxSubArray(int[] nums, int k) {
           if(nums ==null || nums.length == 0)
                return 0;
            int len = nums.length;
            //以j结尾的数组里有i个子数组
            //f[i][j] = Math.max(f[i][j], f[i-1][m]+ sumFromTo(i-1,j]);
            int localMax, max;
            int[][] f = new int[k+1][len+1];
            int min = nums[0], sum = 0;
            for(int i = 1; i <= k; i++){
                    for(int j = i; j <= len; j++){
                        localMax = 0; max = Integer.MIN_VALUE;
                        f[i][j] = Integer.MIN_VALUE;
                        for(int m = j-1; m >= i-1; m--){//i->j之间最大的subarray sum,需要从后往前算,这样求的是后端固定的maxSum
                            //从后往前,因为我们只需要从j-1到i-1内最大的,前面开始的话包括了i-1之前的值。和back-forward概念一样
                            //locaMax一定以当年Nums[m]结尾的sum,但是max不一定以当前结尾,而是截止到m为止最大,可有该nums[m]可无
                              localMax = Math.max(nums[m], localMax + nums[m]);
                             max = Math.max(localMax, max);
                             f[i][j] = Math.max(f[i][j], f[i-1][m]+ max);
                        }

                }   
            }
            return f[k][len];
    }

分析:

local[i][k]表示前i个元素取k个子数组并且必须包含第i个元素的最大和。

global[i][k]表示前i个元素取k个子数组不一定包含第i个元素的最大和。

local[i][k]的状态函数:

local有两种情况,第一种是第i个元素自己组成一个子数组,则要在前i-1个元素中找k-1个子数组,第二种情况是第i个元素属于前一个元素的子数组,因此要在i-1个元素中找k个子数组(并且必须包含第i-1个元素,这样第i个元素才能合并到最后一个子数组中),取两种情况里面大的那个。

global[i][k]的状态函数:

glocal有两种情况,第一种是不包含第i个元素,所以要在前i-1个元素中找k个子数组,第二种情况为包含第i个元素,在i个元素中找k个子数组且必须包含第i个元素,取两种情况里面大的那个

Last updated

Was this helpful?