반응형
1. 속도 개선 아이디어
각 문자가 나타난 횟수를 미리 저장해둔다.
예를들어 S = CAGCCTA 일 때, 다음과 같이 부분 합(Prefix Sums)을 생각해 볼 수 있다.
| index | 문자열S | A | C | G | T |
| 0 | 초기 상태 | 0 | 0 | 0 | 0 |
| 1 | C | 0 | 1 | 0 | 0 |
| 2 | CA | 1 | 1 | 0 | 0 |
| 3 | CAG | 1 | 1 | 1 | 0 |
| 4 | CAGC | 1 | 2 | 1 | 0 |
| 5 | CAGCC | 1 | 3 | 1 | 0 |
| 6 | CAGCCT | 1 | 3 | 1 | 1 |
| 8 | CAGCCTA | 2 | 3 | 1 | 1 |
P = 2, Q = 4 를 생각해보자.
S[2]까지의 부분합은 [1, 1, 0, 0] 이다.
S[4]까지의 부분합은 [1, 3, 1, 0] 이다. (초기 상태가 있기 때문에, index 5를 봐야한다.)
이제 S[4] - S[2]를 해보면, [0, 2, 1, 0] 임을 알 수 있다. 즉, S[2] ~ S[4] 구간에서 C와 G가 나타났음을 알 수 있다.
2. C++ (코드)
vector<int> solution(string &S, vector<int> &P, vector<int> &Q) {
//부분 합 구하기
vector<int> A(S.size() + 1, 0);
vector<int> C(S.size() + 1, 0);
vector<int> G(S.size() + 1, 0);
vector<int> T(S.size() + 1, 0);
for(size_t i = 0; i < S.size(); i++)
{
A[i + 1] = A[i];
C[i + 1] = C[i];
G[i + 1] = G[i];
T[i + 1] = T[i];
if(S[i] == 'A') A[i + 1]++;
else if(S[i] == 'C') C[i + 1]++;
else if(S[i] == 'G') G[i + 1]++;
else T[i]++;
}
//가장 작은 문자 찾기
vector<int> result;
for(size_t M = 0; M < P.size(); M++)
{
int start = P[M];
int end = Q[M];
if(A[end + 1] - A[start] > 0) result.emplace_back(1);
else if(C[end + 1] - C[start] > 0) result.emplace_back(2);
else if(G[end + 1] - G[start] > 0) result.emplace_back(3);
else result.emplace_back(4);
}
return result;
}
3. 결과

반응형
'Algorithm Problem > Codility' 카테고리의 다른 글
| Lesson 5. Perfix Sums - MinAvgTwoSlice #2 (속도 개선) (0) | 2024.11.03 |
|---|---|
| Lesson 5. Perfix Sums - MinAvgTwoSlice #1 (0) | 2024.11.03 |
| Lesson 5. Perfix Sums - GenomicRangeQuery #1 (0) | 2024.10.26 |
| Lesson 5. Perfix Sums - CountDiv #2 (속도 개선) (0) | 2024.10.21 |
| Lesson 5. Perfix Sums - CountDiv #1 (0) | 2024.10.21 |