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