LintCode--最大子数组差

LintCode--maximum-subarray-difference(最大子数组差)

原题链接:http://www.lintcode.com/zh-cn/problem/maximum-subarray-difference/


给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大。

返回这个最大的差值。

样例

给出数组[1, 2, -3, 1],返回 6

注意

子数组最少包含一个数


分析:

定义两个数组dp[0][0..n-1],dp[1][0..n-1]。从后遍历数组,dp[0][ i ]表示从i..n-1的最小子序列和,dp[1][ i ]表示从i..n-1的最大子序列和。

然后从头遍历数组,计算[0..i]的最大(小)子序列和与[i+1..n-1]的最小(大)子序列和的差的绝对值的最大值。

#时间复杂度 O(n),空间复杂度O(n)


代码(C++、Python、Java):

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer indicate the value of maximum difference between two
     *          Subarrays
     */
    int max(int a, int b){
        if (a > b) return a;
        else return b;
    }
    
    int maxDiffSubArrays(vector<int> nums) {
        // write your code here
        int n = nums.size();
        if (n <= 1) return 0;
        int dp[2][n+10];
        int res = 0;             //result
        int sum1 = 0, sum2 = 0, minsub = 0, maxsub = 0;
        int minn = nums[n-1], maxx = nums[n-1];
        for (int i = n-1; i >= 0; i--){
            sum1 += nums[i], sum2 += nums[i];
            if (sum1 > 0) sum1 = 0;
            if (sum1 < minsub) minsub = sum1;
            if (minn > nums[i]) minn = nums[i];
            if (sum2 < 0) sum2 = 0;
            if (sum2 > maxsub) maxsub = sum2;
            if (maxx < nums[i]) maxx = nums[i];
            /* dp[0] for the minmum subarray sum, dp[1] for the maximum subarry sum */
            if (minn >= 0) 
                dp[0][i] = minn;
            else 
                dp[0][i] = minsub;
            if (maxx <= 0) 
                dp[1][i] = maxx;
            else 
                dp[1][i] = maxsub;
        }
        sum1 = 0, sum2 = 0, minsub = 0, maxsub = 0;
        minn = nums[0], maxx = nums[0];
        for (int i = 0; i < n-1; i++){
            sum1 += nums[i],sum2 += nums[i];
            if (sum1 > 0) sum1 = 0;
            if (sum1 < minsub) minsub = sum1;
            if (minn > nums[i]) minn = nums[i];
            if (sum2 < 0) sum2 = 0;
            if (sum2 > maxsub) maxsub = sum2;
            if (maxx < nums[i]) maxx = nums[i];
            if (minn >= 0) 
                res = max(res, abs(minn - dp[1][i+1]));
            else 
                res = max(res, abs(minsub - dp[1][i+1]));
            if (maxx <= 0) 
                res = max(res, abs(maxx - dp[0][i+1]));
            else 
                res = max(res, abs(maxsub - dp[0][i+1]));
        }
        return res;
    }
};

public class Solution {
    /**
     * @param nums: A list of integers
     * @return: An integer indicate the value of maximum difference between two
     *          Subarrays
     */
    int max(int a, int b){
        if (a > b) return a;
        else return b;
    }
    int abs(int a){
        if (a > 0) return a;
        else return -a;
    } 
    
    public int maxDiffSubArrays(ArrayList<Integer> nums) {
        // write your code
        int n = nums.size();
        if (n <= 1) return 0;
        int [][] dp = new int [2][n+10];
        int res = 0;             //result
        int sum1 = 0, sum2 = 0, minsub = 0, maxsub = 0;
        int minn = nums.get(n-1), maxx = nums.get(n-1);
        for (int i = n-1; i >= 0; i--){
            sum1 += nums.get(i);
            sum2 += nums.get(i);
            if (sum1 > 0) sum1 = 0;
            if (sum1 < minsub) minsub = sum1;
            if (minn > nums.get(i)) minn = nums.get(i);
            if (sum2 < 0) sum2 = 0;
            if (sum2 > maxsub) maxsub = sum2;
            if (maxx < nums.get(i)) maxx = nums.get(i);
            /* dp[0] for the minmum subarray sum, dp[1] for the maximum subarry sum */
            if (minn >= 0) 
                dp[0][i] = minn;
            else 
                dp[0][i] = minsub;
            if (maxx <= 0) 
                dp[1][i] = maxx;
            else 
                dp[1][i] = maxsub;
        }
        sum1 = 0;
        sum2 = 0;
        minsub = 0;
        maxsub = 0;
        minn = nums.get(0);
        maxx = nums.get(0);
        for (int i = 0; i < n-1; i++){
            sum1 += nums.get(i);
            sum2 += nums.get(i);
            if (sum1 > 0) sum1 = 0;
            if (sum1 < minsub) minsub = sum1;
            if (minn > nums.get(i)) minn = nums.get(i);
            if (sum2 < 0) sum2 = 0;
            if (sum2 > maxsub) maxsub = sum2;
            if (maxx < nums.get(i)) maxx = nums.get(i);
            if (minn >= 0) 
                res = max(res, abs(minn - dp[1][i+1]));
            else 
                res = max(res, abs(minsub - dp[1][i+1]));
            if (maxx <= 0) 
                res = max(res, abs(maxx - dp[0][i+1]));
            else 
                res = max(res, abs(maxsub - dp[0][i+1]));
        }
        return res;
    }
}

class Solution:
    """
    @param nums: A list of integers
    @return: An integer indicate the value of maximum difference between two
             Subarrays
    """
    def maxDiffSubArrays(self, nums):
        # write your code here
        n = len(nums)
        if n <= 1:
            return 0
        dp = [[0 for i in range(n+10)] for i in range(2)]
        res = 0
        sum1 = 0
        sum2 = 0
        minsub = 0
        maxsub = 0
        minn = nums[n-1]
        maxx = nums[n-1]
        for i in list(reversed(range(n))):
            sum1 += nums[i]
            sum2 += nums[i]
            if sum1 > 0:
                sum1 = 0
            if sum1 < minsub:
                minsub = sum1
            if minn > nums[i]:
                minn = nums[i]
            if sum2 < 0:
                sum2 = 0
            if sum2 > maxsub:
                maxsub = sum2
            if maxx < nums[i]:
                maxx = nums[i]
            #dp[0] for the minumun subarray sum, dp[1] for the maximum subarray sum
            if minn >= 0:
                dp[0][i] = minn
            else:
                dp[0][i] = minsub
            if maxx <= 0:
                dp[1][i] = maxx
            else:
                dp[1][i] = maxsub
        sum1 = 0
        sum2 = 0
        minsub = 0
        maxsub = 0
        minn = nums[0]
        maxx = nums[0]
        for i in range(n-1):
            sum1 += nums[i]
            sum2 += nums[i]
            if sum1 > 0:
                sum1 = 0
            if sum1 < minsub:
                minsub = sum1
            if minn > nums[i]:
                minn = nums[i]
            if sum2 < 0:
                sum2 = 0
            if sum2 > maxsub:
                maxsub = sum2
            if maxx < nums[i]:
                maxx = nums[i]
            if minn >= 0:
                res = max(res, abs(minn - dp[1][i+1]))
            else:
                res = max(res, abs(minsub - dp[1][i+1]))
            if maxx <= 0:
                res = max(res, abs(maxx - dp[0][i+1]))
            else:
                res = max(res, abs(maxsub - dp[0][i+1]))
        return res
                
def max(a, b):
    if a > b:
        return a
    else:
        return b




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值