lintcode 中等题:maximum subarray difference 最大子数组差

题目

最大子数组差

给定一个整数数组,找出两个不重叠的子数组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);
    }
}

Java Code

显然上面程序太冗余了

这里的方法和我想的一样

这里也是的,只是部分循环在一起写了

优化下

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);
    }
}

Java Code

简书程序

好像就这个方法了

时间: 2024-10-16 20:53:46

lintcode 中等题:maximum subarray difference 最大子数组差的相关文章

lintcode 中等题:Maximal Square 最大子正方形

题目: Maximal Square Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area. 样例 For example, given the following matrix: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Return 4. 解题: 给定一个二维01矩阵,从中找出最大的全

[lintcode medium]Maximum Subarray Difference

Maximum Subarray Difference Given an array with integers. Find two non-overlapping subarrays A and B, which |SUM(A) - SUM(B)| is the largest. Return the largest difference. Example For [1, 2, -3, 1], return 6. Note The subarray should contain at leas

【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】

[053-Maximum Subarray(最大子数组和)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [?2,1,?3,4,?1,2,1,?5,4], the contiguous subarra

lintcode 中等题:maximum subarray最大子数组II

题目 最大子数组 II 给定一个整数数组,找出两个不重叠子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[1, 3, -1, 2, -1, 2],这两个子数组分别为[1, 3]和[2, -1, 2]或者[1, 3, -1, 2]和[2],它们的最大和都是7 注意 子数组最少包含一个数 挑战 要求时间复杂度为O(n) 解题 最大子数组I 这个题目是求一个数组中一个最大子数组的和,而本题目是求数组中的前

lintcode 中等题:continuous subarray sum 联系子数组之和

题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, 1, 3, -3, 4], 返回[1,4]. 解题 法一:直接暴力,时间复杂度O(N2),时间超时 public class Solution { /** * @param A an integer array * @return A list of integers includes the i

Maximum Product Subarray 求最大子数组乘积

这个求最大子数组乘积问题是由最大子数组之和问题演变而来,但是却比求最大子数组之和要复杂,因为在求和的时候,遇到0,不会改变最大值,遇到负数,也只是会减小最大值而已.而在求最大子数组乘积的问题中,遇到0会使整个乘积为0,而遇到负数,则会使最大乘积变成最小乘积,正因为有负数和0的存在,使问题变得复杂了不少.. 比如,我们现在有一个数组[2, 3, -2, 4],我们可以很容易的找出所有的连续子数组,[2], [3], [-2], [4], [2, 3], [3, -2], [-2, 4], [2,

[LeetCode] 152. Maximum Product Subarray 求最大子数组乘积

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product. Example 1: Input: [2,3,-2,4] Output: 6 Explanation: [2,3] has the largest product 6. Example 2: Input: [-2,0,-1]

leetcode_53题——Maximum Subarray(动态规划)

Maximum Subarray Total Accepted: 62857 Total Submissions: 182415My Submissions Question Solution Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [−2,1,−3,4,−1,2,1,−

Maximum Subarray Difference

该题的思路是使用辅助数组来保存从前向后和从后向前到当前位置的最大最小值,这样就可以通过每一个位置处的最大最小值来计算该位置的结果,最后在所有结果中选出最大的值即可. int maxDiffSubArrays(vector<int> nums) { // write your code here int size = nums.size(); //以数组中数的个数为维度,定义四个辅助数组 int *maxArray = new int[size]; int *preMinArray = new