[LintCode] Maximum Subarray Difference | 双向遍历找子数组差的绝对值的最大值

http://www.lintcode.com/zh-cn/problem/maximum-subarray-difference/#

这个问题和最大化两个不重叠子数组和类似,即还是想办法求得区间[0...i][i+1...n-1]的最大/小连续子数组和,只是不同的是要最大化相减的绝对值。那么就对两个区间都分别预处理好最大值和最小值,答案一定是其中一个的最大值与另一个的最小值之差。

int maxDiffSubArrays(vector<int> &nums) {
    if (nums.empty()) return 0;
    
    int n = nums.size();
    
    // 思路:对所有的i,分别预处理好区间[0...i]和[i+1...n-1]的子数组最大值和最小值
    // 然后结果是max(left_max[i] - right_min[i+1]), max(left_min[i] - right_max[i])两个较大的那个
    vector<int> left_max(n), left_min(n), right_max(n), right_min(n);
    
    int prev_max = nums[0], prev_min = nums[0], cur_max, cur_min;
    left_max[0] = nums[0]; left_min[0] = nums[0];
    for (int i = 1; i < n - 1; ++i) {
        if (prev_max > 0) cur_max = prev_max + nums[i];
        else cur_max = nums[i];
        if (prev_min < 0) cur_min = prev_min + nums[i];
        else cur_min = nums[i];
        left_max[i] = max(left_max[i-1], cur_max);
        left_min[i] = min(left_min[i-1], cur_min);
        prev_max = cur_max;
        prev_min = cur_min;
    }
    
    prev_max = nums[n-1]; prev_min = nums[n-1];
    right_max[n-1] = nums[n-1]; right_min[n-1] = nums[n-1];
    for (int i = n - 2; i > 0; --i) {
        if (prev_max > 0) cur_max = prev_max + nums[i];
        else cur_max = nums[i];
        if (prev_min < 0) cur_min = prev_min + nums[i];
        else cur_min = nums[i];
        right_max[i] = max(right_max[i+1], cur_max);
        right_min[i] = min(right_min[i+1], cur_min);
        prev_max = cur_max;
        prev_min = cur_min;
    }
    
    int ret = 0;
    for (int i = 0; i < n - 1; ++i) {
        ret = max(ret, max(abs(left_max[i]-right_min[i+1]), abs(left_min[i]-right_max[i+1])));
    }
    return ret;
}
posted @ 2017-09-14 09:46  mioopoi  阅读(243)  评论(0编辑  收藏  举报