标签:
题目
给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大。
返回这个最大的差值。
给出数组[1, 2, -3, 1],返回 6
子数组最少包含一个数
时间复杂度为O(n),空间复杂度为O(n)
解题
刚做了数组中两个子数组和的最大值,这一题是求差,感觉上题的求解思想应该是可以用的
A B 分别是两个子数组的和,则:
所以
当A>B 的时候A越大越好 B越小越好
当A<B 的时候B越大越好 A越小越好
根据上一题的思想,定义leftMax数组,leftMax[i] 表示0到 i之间元素的全局最大值,定义rightMin矩阵,rightMin [i] 表示i 到 len -1 之间元素的全局最小值
这样abs(leftMax[i] - rightMin[i+1]) 就是0到i 之间元素的最大值 减去 i + 1 到len-之间元素最小值 的绝对值,这个值得最大值就是两个子区间的 差的绝对值的最大值
注意,这样还是有问题的,只是上面提交只能通过53%
上面只是考虑的 A>B的情况,还需要考虑A<B的情况
A >B 的情况是:leftMax - rightMin
A<B 的情况是:rightMax - leftMin,具体思路参考上面的
这样求出两个最大值的最大值就是答案了
public class Solution { /** * @param nums: A list of integers * @return: An integer indicate the value of maximum difference between two * Subarrays */ public int maxDiffSubArrays(int[] nums) { // write your code here if(nums == null || nums.length ==0) return 0; int len = nums.length; int[] leftMax = new int[len]; int[] rightMin = new int[len]; int localMax = 0; int globalMax = Integer.MIN_VALUE; for(int i=0;i <len ;i++){ localMax = Math.max(localMax + nums[i],nums[i]); globalMax = Math.max(localMax,globalMax); leftMax[i] = globalMax; } int localMin = 0; int globalMin = Integer.MAX_VALUE; for(int i=len-1;i >=0 ;i--){ localMin = Math.min(localMin + nums[i],nums[i]); globalMin = Math.min(localMin,globalMin); rightMin[i] = globalMin; } int leftMAX = Integer.MIN_VALUE; for(int i=0;i<len-1;i++){ leftMAX = Math.max(Math.abs(leftMax[i] - rightMin[i+1]),leftMAX); } int[] leftMin = new int[len]; int[] rightMax = new int[len]; localMin = 0; globalMin = Integer.MAX_VALUE; for(int i=0;i <len ;i++){ localMin = Math.min(localMin + nums[i],nums[i]); globalMin = Math.min(localMin,globalMin); leftMin[i] = globalMin; } localMax = 0; globalMax = Integer.MIN_VALUE; for(int i=len-1;i >=0 ;i--){ localMax = Math.max(localMax + nums[i],nums[i]); globalMax = Math.max(localMax,globalMax); rightMax[i] = globalMax; } int rightMAX = Integer.MIN_VALUE; for(int i=0;i<len-1;i++){ rightMAX = Math.max(Math.abs(leftMin[i] - rightMax[i+1]),rightMAX); } return Math.max(leftMAX,rightMAX); } }
显然上面程序太冗余了
这里的方法和我想的一样
这里也是的,只是部分循环在一起写了
优化下
public class Solution { /** * @param nums: A list of integers * @return: An integer indicate the value of maximum difference between two * Subarrays */ public int maxDiffSubArrays(int[] nums) { // write your code here if(nums == null || nums.length ==0) return 0; int len = nums.length; int[] leftMax = new int[len]; int[] rightMin = new int[len]; int[] leftMin = new int[len]; int[] rightMax = new int[len]; int localMax = 0; int globalMax = Integer.MIN_VALUE; int localMin = 0; int globalMin = Integer.MAX_VALUE; for(int i=0;i <len ;i++){ localMax = Math.max(localMax + nums[i],nums[i]); globalMax = Math.max(localMax,globalMax); leftMax[i] = globalMax; localMin = Math.min(localMin + nums[i],nums[i]); globalMin = Math.min(localMin,globalMin); leftMin[i] = globalMin; } localMin = 0; globalMin = Integer.MAX_VALUE; localMax = 0; globalMax = Integer.MIN_VALUE; for(int i=len-1;i >=0 ;i--){ localMin = Math.min(localMin + nums[i],nums[i]); globalMin = Math.min(localMin,globalMin); rightMin[i] = globalMin; localMax = Math.max(localMax + nums[i],nums[i]); globalMax = Math.max(localMax,globalMax); rightMax[i] = globalMax; } int leftMAX = Integer.MIN_VALUE; int rightMAX = Integer.MIN_VALUE; for(int i=0;i<len-1;i++){ leftMAX = Math.max(Math.abs(leftMax[i] - rightMin[i+1]),leftMAX); rightMAX = Math.max(Math.abs(leftMin[i] - rightMax[i+1]),rightMAX); } return Math.max(leftMAX,rightMAX); } }
好像就这个方法了
lintcode 中等题:maximum subarray difference 最大子数组差
标签:
原文地址:http://www.cnblogs.com/theskulls/p/5106830.html