最大子串和问题
2014-07-08 22:58
337 查看
question:
Given an array that has positive and negative numbers, try to find a maximum subarray whose sum is the best.
暴力解法: 复杂度(N^2)
pseudo-code:
FIND-MAXIMUM-SUBARRAY(A, low, high)
sum = INT_MIN
for i = low to high - 1
tmp_sum = A[i]
for j = i + 1 to high
tmp_sum = tmp_sum + A[j]
if tmp_sum > sum
sum = tmp_sum
left = i
right = j
return (left, right, sum)
分治法: 复杂度(NlogN)
pseudo-code:
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left-sum = INT_MIN
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left-sum
left-sum = sum
max-left = i
right-sum = INT_MIN
sum = 0
for j = mind + 1 to high
sum = sum + A[j]
if sum > right-sum
left-sum = sum
max-right = j
return(max-left, max-right, left-sum + right-sum)
FIND-MAXIMUM-SUBARRAY(A, low, high)
if low = high
return (low, high, A[low])
else mid = (low + high) / 2
(left-low, left-high, left-sum) =
FIND-MAXIMUM-SUBARRAY(A, low, mid)
(right-low, right-high, right-sum) =
FIND-MAXIMUM-SUBARRAY(A, mid + 1, high)
(cross-low, cross-high, cross-sum) =
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
if left-sum >= right-sum and left-sum >= cross-sum
return (left-low, left-high, left-sum)
elseif right-sum >= left-sum and right-sum >= cross-sum
return (right-low, right-high, right-sum)
else return (cross-low, cross-high, cross-sum)
C语言实现:
线性解法:复杂度(N)
<1>Analyse
从数组左边界开始,从左到右处理,记录到目前为止最大子数组的。若已知A[1....j]的最大子数组,基于如下性质将解扩展为A[1....j + 1]的最大子数组:
A[1....j + 1]的最大子数组为 A[1....j] 的最大子数组或A[i....j + 1] (1 <= i <= j + 1)。
性质分析:
若A[j + 1] >= 0, 并且最大子数组为 A[i....j], 那么A[1....j + 1]最大子数组为A[i....j + 1];
若A[j + 1] >= 0,若最大子数组为A[m....n] (1 <= m < n, n < j),那么 A[1....j + 1]最大子数组为A[1.....j]中最大子数组或A[i....j + 1], A[i...j + 1]满足不存在k (j > k > i)使A[i]+ A[i + 1]..+A[k] < 0
若A[j + 1] < 0, 并且最大子数组为 A[m....n] (1 <=m < n, n <= j),那么A[1...j + 1]中最大子数组为A[m...n];
pseudo-code:
FIND-MAXIMUM-SUBARRAY(A, low, high)
sum = INT_MIN
max = INT_MIN
for i = low to high
if max < 0
max = A[i]
else max = max + A[i]
if sum < max
sum = max
return sum
c语言实现:
备注:
When all the numbers are negative, the function will return the minimun number of the array;
Given an array that has positive and negative numbers, try to find a maximum subarray whose sum is the best.
暴力解法: 复杂度(N^2)
pseudo-code:
FIND-MAXIMUM-SUBARRAY(A, low, high)
sum = INT_MIN
for i = low to high - 1
tmp_sum = A[i]
for j = i + 1 to high
tmp_sum = tmp_sum + A[j]
if tmp_sum > sum
sum = tmp_sum
left = i
right = j
return (left, right, sum)
typedef struct { int low ; int high ; int sum ; } Array_Info; Array_Info Find_Maximum_Subarray_Force (int A[], int low , int high ) { Array_Info result ; int i , j ; int sum ; result .sum = INT_MIN ; for ( i = low; i < high ; i ++) { sum = A[ i ]; for ( j = i + 1 ; j <= high ; j ++) { sum += A[ j ]; if ( sum > result. sum ) { result .low = i ; result .high = j ; result .sum = sum ; } } } return result ; } // can not to solve the array that all the numbers are negitive
分治法: 复杂度(NlogN)
pseudo-code:
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left-sum = INT_MIN
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left-sum
left-sum = sum
max-left = i
right-sum = INT_MIN
sum = 0
for j = mind + 1 to high
sum = sum + A[j]
if sum > right-sum
left-sum = sum
max-right = j
return(max-left, max-right, left-sum + right-sum)
FIND-MAXIMUM-SUBARRAY(A, low, high)
if low = high
return (low, high, A[low])
else mid = (low + high) / 2
(left-low, left-high, left-sum) =
FIND-MAXIMUM-SUBARRAY(A, low, mid)
(right-low, right-high, right-sum) =
FIND-MAXIMUM-SUBARRAY(A, mid + 1, high)
(cross-low, cross-high, cross-sum) =
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
if left-sum >= right-sum and left-sum >= cross-sum
return (left-low, left-high, left-sum)
elseif right-sum >= left-sum and right-sum >= cross-sum
return (right-low, right-high, right-sum)
else return (cross-low, cross-high, cross-sum)
C语言实现:
typedef struct { int low ; int high ; int sum ; } Array_Info; Array_Info Find_Max_Crossing_Subarray (int A[], int low , int mid , int high ) { int i , j ; int max_left , max_right ; int left_sum = INT_MIN ; int sum = 0 ; Array_Info cross ; for ( i = mid; i >= 0 ; i --) { sum += A[ i ]; if ( sum > left_sum) { left_sum = sum; max_left = i; } } int right_sum = INT_MIN ; sum = 0; for ( j = mid + 1 ; j <= high ; j ++) { sum += A[ j ]; if ( sum > right_sum) { right_sum = sum; max_right = j; } } cross .low = max_left ; cross .high = max_right ; cross .sum = left_sum + right_sum; return cross ; } Array_Info Find_Maximum_Subarray( int A [], int low, int high ) { Array_Info base , left , right , cross ; if ( low == high) { base .low = low ; base .high = high ; base .sum = A [low ]; return base ; } int mid = ( low + high ) / 2; left = Find_Maximum_Subarray( A , low , mid ); right = Find_Maximum_Subarray( A , mid + 1, high); cross = Find_Max_Crossing_Subarray (A , low , mid , high ); if ( left .sum >= right .sum && left .sum >= cross .sum ) return left ; else if (right . sum >= left . sum && right . sum >= cross . sum) return right ; else return cross ; }
线性解法:复杂度(N)
<1>Analyse
从数组左边界开始,从左到右处理,记录到目前为止最大子数组的。若已知A[1....j]的最大子数组,基于如下性质将解扩展为A[1....j + 1]的最大子数组:
A[1....j + 1]的最大子数组为 A[1....j] 的最大子数组或A[i....j + 1] (1 <= i <= j + 1)。
性质分析:
若A[j + 1] >= 0, 并且最大子数组为 A[i....j], 那么A[1....j + 1]最大子数组为A[i....j + 1];
若A[j + 1] >= 0,若最大子数组为A[m....n] (1 <= m < n, n < j),那么 A[1....j + 1]最大子数组为A[1.....j]中最大子数组或A[i....j + 1], A[i...j + 1]满足不存在k (j > k > i)使A[i]+ A[i + 1]..+A[k] < 0
若A[j + 1] < 0, 并且最大子数组为 A[m....n] (1 <=m < n, n <= j),那么A[1...j + 1]中最大子数组为A[m...n];
pseudo-code:
FIND-MAXIMUM-SUBARRAY(A, low, high)
sum = INT_MIN
max = INT_MIN
for i = low to high
if max < 0
max = A[i]
else max = max + A[i]
if sum < max
sum = max
return sum
c语言实现:
int Find_Maximum_Subarray ( int A [], int low , int high) { int sum = INT_MIN ; int max = INT_MIN ; for ( int i = low ; i <= high; i++) { if ( max < 0) max = A[ i ]; else max += A[ i ]; if ( sum < max) sum = max; } return sum ; }
备注:
When all the numbers are negative, the function will return the minimun number of the array;
相关文章推荐
- 用动态规划算法对最大子串问题的java实现
- 和最大连续子串的问题
- 动态规划(4)最大连续子串问题
- Maximum Subarray 最大子串和问题(需要重看理论)
- 动态规划--最大连续子串问题
- 字符串中最大子串问题
- 最大子串和--动态规划经典问题
- 最大子串和问题(Maximum Subarray)
- 最大子串和问题(Maximum Subarray)
- 最大子串乘积问题
- 连续子串的最大值(经典的DP问题)
- 最大子串和问题(Maximum Subarray)
- 最大公共连续子串(LCS问题)
- SRM 222 Div II Level One: TextCompressor,求最大重复子串问题
- 最大子串问题(The Maximum-subarray Problem)
- 最大子串问题
- 求和最大的连续子串问题
- 【转】【算法学习】最大子串问题
- HDU 1244 最大m段连续子串问题
- java实现字符串匹配问题之求两个字符串的最大公共子串