부분합 알고리즘은 누적합의 차를 통해 부분합을 구하는 방식으로 빠르게 부분합을 계산하는 알고리즘

 

 

배열을 하나 더 만들어서 index까지의 합을 돌린다음에 이 합을 구한 벡터를 이용하여 특정 범위의 부분합을 구할수있다.

#include <algorithm>

int solution(vector<int> &A) {
    vector<int> B (A.size(), 0);

    B[0] = A[0];
    int _max = B[0];
    for(int i=1; i<A.size(); i++)
    {
        B[i] = max( B[i-1] + A[i] , A[i] ); 
        // 기존 i-1까지 합 B[i-1] + A[i] 를 합친게 큰지
        // 아니면 A[i] 부터 새로 시작하는게 큰지 

        if (_max < B[i])
            _max = B[i];
    }
    return _max;
}

TimeComplex: O(n)

SpaceComplex: O(n)

 

 

Colidity - MaxSliceSum

https://app.codility.com/programmers/lessons/9-maximum_slice_problem/

 

9. Maximum slice problem lesson - Learn to Code - Codility

Given a log of stock prices compute the maximum possible earning.

app.codility.com

 

 

 

index기준으로 합 나눌 때

ex) sum1 = A[0] + A[1] ... A[i-1],   sum2 = A[i] + A[i+1] .. A[A.size()-1]

마찬가지로 배열을 한번 순회하여 합을 구한다음에

start = 0, last = sum 으로 초기화하고 인덱스에맞춰 start에는 더하고 last에는 뺀다.

#include <algorithm>

int solution(vector<int> &A) {
    
    int sum = 0;
    for(int i=0; i<A.size(); i++)
        sum += A[i];
    
    int num = 0;
    int _min = 100000000; // 1,000 * 100,000

    for(int i=0; i<A.size()-1; i++)
    {
        num += A[i];
        sum -= A[i];

        int tmp = abs(num - sum);
        // cout << num << " " << sum << "  tmp: " << tmp <<endl;

        if (_min > tmp)
            _min = tmp; 
    }
    return _min;
}

 

Colidity - TapeEquilibrium

https://app.codility.com/programmers/lessons/3-time_complexity/

 

3. Time Complexity lesson - Learn to Code - Codility

Count minimal number of jumps from position X to Y.

app.codility.com

 

 

또한 index에 따른 부분합의 최대값을 구할때는 다음과 같이 구할 수 있다.

sum_A[0] = A[0];
for(int i=1; i<A.size()-1; i++)
    sum_A[i] = max(sum_A[i-1] + A[i], A[i]);

(바로 앞 index 까지의 부분합 + 현재 index의 원소) 보다 (현재 index의 원소) 가 크면 굳이 앞의 부분합을 더하면 손해이므로 더해줄 필요가없다

 

 

 

#include <algorithm>

int solution(vector<int> &A) {

    vector<int> front_B(A.size(), 0);
    vector<int> back_B(A.size(), 0);

    front_B[0] = 0;
    for(int i=1; i<A.size()-1; i++)
        front_B[i] = max(0, front_B[i-1] + A[i]);
    // Math.max(0, value)처럼 0과 비교해 주는 이유는, X,Y가 인접한 경우와 Y,Z가 인접한 경우 값이 0이므로 값으로 넣을 수 있는 가장 작은 값  
    // ex) double slice (3, 4, 5)

    back_B[A.size()-1] = 0;
    for(int i=A.size()-2; i>0; i—)
        back_B[i] = max(0, back_B[i+1] + A[i]);

    int _max = -1000000000; // -10,000 * 100,000
    for(int i=1; i<A.size()-1; i++)
        _max = max(_max, front_B[i-1] + back_B[i+1]);
    
    return _max;
}

Colidity - MaxDoubleSliceSum

https://app.codility.com/programmers/lessons/9-maximum_slice_problem/

 

9. Maximum slice problem lesson - Learn to Code - Codility

Given a log of stock prices compute the maximum possible earning.

app.codility.com

 

'알고리즘' 카테고리의 다른 글

유클리드 호제법 (Euclidean Algorithm)  (0) 2022.08.18

+ Recent posts