Maximum sub-array problem

Source: Internet
Author: User
Tags function definition
Maximum sub-array problem

This article is just a record, more detailed ideas please view the introduction of algorithms

Maximum sub-array structure body

typedef struct {    int low, high, sum;} SubArray;

Brute Force Solution
Computes all the array intervals and then gets the largest sub-array, the algorithm complexity is θ (n²). This approach is good for small-scale data, but it is bad in large-scale data, but it can be used as an improvement in the divide-and-conquer algorithm. The idea is to first calculate the i maximum number of sub-arrays from the beginning, and then from [1..N],[2..N]. [N.. N] to find the largest sub-array.

  subarray maxsubarray_bruteforce (int low, int. high, int a[]) {int sum;    int max_subarray = 0;    Subarray *s = (Subarray *) calloc ((high-low + 2), sizeof (Subarray));        for (int i = low, k = 0; I <= high; ++i, ++k) {s[k].sum = Int_min;        S[k].low = i;        sum = 0;            for (int j = i, J <= High; ++j) {//calculates the maximum subarray from the start with ' i ' sum + = a[j];                if (S[k].sum < sum) {s[k].sum = sum;            S[k].high = j; }} if (S[max_subarray].sum <= s[k].sum)//= is the case where {0,0,1} is present the exact computed sub-array is [2,2]{1} max_sub    Array = I-low; } return S[max_subarray];}  

Divide and conquer algorithm
From the time analysis of the divide-and-conquer algorithm,
$$
T (n) =\begin{cases}
\theta (1) & if & n = 1 \
A\theta (n/a) + \theta (n.) & if & n > 1
\end{cases}
$$
If you are looking for [low. High], using the technique of divide and conquer means that we want to divide the array into two sub-arrays of the same size as possible (top A is 2), find the middle position mid, and then consider solving the sub-array [Low. Mid] and [Mid+1..high]. Array [Low.. Maximum sub-array of high] [I.. J] must be the following three cases:

    • Exactly in the sub-array [Low.. Mid], solow <= i <= high <= mid
    • is completely in the sub-array [Mid+1..high], somid+1 <= i <= j <= high
    • Midpoint mid is cross-domain, so it's locatedlow <= i <= mid <= j <= high

and specify that the array across the midpoint must contain mid and Mid + 1

To solve a sub-array recursively [low.. Mid] and [Mid+1..high], reducing the size of the problem, and finally looking for the largest sub-array across the midpoint, similar to the merging process of the merge sort, we take the largest sub-array that crosses the midpoint as the merging process of sub-problems. The simple logic is

    1. Looking for sub-arrays [Low: The largest sub-array of mid]
    2. Finding the largest subarray of sub-arrays [Mid+1..high]
    3. Looking for [low.. The largest sub-array of mid Mid+1..high]
    4. Returns a subarray of three maximum sub-arrays. Note: The comparison here must be preceded by an equal sign, so that you can skip over 0 to find the maximum subarray more precisely.
 subarray maxcrosssubarray (int low, int mid, int. High, int a[]) {int left_sum, right_sum, sum; Subarray S; Left_sum = Right_sum = Int_min; sum = 0; for (int i = Mid, I >= low; i--) {sum + = A[i]; if (Left_sum < sum) {s.low = i; Left_sum = sum; }} sum = 0; for (int j = mid + 1, J <= High; j + +) {sum + = a[j]; if (Right_sum < sum) {S.high = J; Right_sum = sum; }} s.sum = Left_sum + right_sum; return S;} Subarray maxsubarray_divideconquer (int low, int. High, Int. a[]) {if (low = = high) {Subarray S; S.low = low; S.high = high; S.sum = A[low]; return S; } int mid = (low + high)/2; Subarray L = Maxsubarray_divideconquer (Low, Mid, A); Subarray R = Maxsubarray_divideconquer (mid + 1, high, A); Subarray M = Maxcrosssubarray (Low, Mid, High, A); Return Max3 (L, R, M);}  

Improved recursive algorithm
The above mentioned brute force solution is very poor in large-scale data, but it has great advantages in small-scale solution. When the size of a sub-problem is less than a certain value n , we use brute force algorithms to solve

// 暴力算法和分治算法在 40 左右达到性能交叉点// 在规模在 10 左右,暴力算法大幅领先分治算法SubArray MaxSubArray_Synergy(int low, int high, int A[]) {    if (high - low < 10)        return MaxSubArray_BruteForce(low, high, A);    int mid = (low + high) / 2;    SubArray L = MaxSubArray_Synergy(low, mid, A);    SubArray R = MaxSubArray_Synergy(mid + 1, high, A);    SubArray M = MaxCrossSubArray(low, mid, high, A);    return Max3(L, R, M);}

Linear algorithm
The largest subarray of known [1..J], calculates the idea of [1..j+1] maximal subarray: The largest subarray of [1..j+1] is either the largest sub-array of [1..J] or a subarray [i. J+1] (1 <= i <= j+1). Specific implementations as described in the notes

SubArray MaxSubArray_Linear(int low, int high, int A[]) {    SubArray S = {-1, -1, INT_MIN};    int sum = 0;    int slow = -1;    for (int i = low; i <= high; ++i) {        if (sum > 0) {          // 加上A[i]后当前最大子数组为正,中间的非负数项继续保留            sum += A[i];        } else {                // 重新寻找最大子数组            sum = A[i];            slow = i;        }        if (sum > S.sum) {      // 新的最大子数组大于旧最大子数组            S.low = slow;            S.high = i;            S.sum = sum;        }    }    

Some of the problems that are encountered while writing code

    • At first, my recursive implementation is also a subarray pointer, but in memory the real subarray only one copy, every time the calculation subarray variable is changing. In fact, we only need the subscript and the sub-array, so directly within the function definition wait until the function end stack memory recycling is not related, because it has been returned.
    • The first I of the brute-force algorithm starts with 0, and if it's just a simple call, it's not going to be a problem, but when the recursive algorithm takes a small call, a segment error occurs (out of bounds)
    • The maximum subarray size is the same, but the subscript of several algorithms is not the same, the problem is that there is no 0 filtering, as in the linear algorithm should be if (Sum > 0) and should not be if (sum >= 0), the Max3 of the recursive algorithm to compare the largest sub-array of the problem should be coupled with an equal judgment. There is also this situation {1, 1,-2, 1, 1}, these algorithms appear two answers [0-1] and [3-4], this problem is not resolved

The time complexity of the four algorithms:
$$
\begin{cases}
Bruteforce & \theta (n^2) & \
Divideconquer & \theta (Nlog (n)) \
Bruteforce+divideconquer & \theta (Nlog (n)) \
Linear & \theta (n)
\end{cases}
$$
Processing 10w (why not a larger number, because the brute force algorithm is too slow), the time of four algorithms is probably

    • Brute Force algorithm 15.12s
    • Simple recursive algorithm 0.15s
    • Optimized recursive algorithm 0.12s
    • Linear algorithm ignores 0.003s

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.