programmers/Lv 3
연속 펄스 부분 수열의 합 [자바]
Meluu_
2025. 2. 26. 12:57
🧫 문제 분석
✔️ 출처
📖 문제

문제를 잘못 이해해서 삽질했다.
펄스 수열을 연속 수열에 패턴대로 곱했을때 최댓값이 나오는 연속 펄수 부분수열을 구하는 것이였다.
나는 잘못 이해해서 펄스 수열 처럼 수열의 연속 부분수열이 3,-6,1,-4 이런식으로 1,-1 이런 패턴이 유지되는 연속 부분 수열에만 펄스 부분 수열 1,-1을 곱해서 양수가 되는 것만 합쳐서 최댓값을 구했다.
당연히 틀렸고 이 문제는 사실 펄스 수열은 페이크고
누적합 문제이다.
주어진 수열에
펄스 수열 패턴을 곱해서 2개의 수열로 만든다.
1,-1 패턴을 곱한 수열
-1, 1 패턴을 곱한 수열
이제 누적합으로 풀면 된다.
나는 누적합 하면서 최댓값과 최솟값을 구하고
최댓값 - 최솟값을 하되 최댓값 -최솟값 < 최댓값이 더 큰 경우가 있다.
-3 5 7 같은 경우 최댓값 9 최솟값 -3이다.
이런 경우는 최솟값을 빼주면 12로 진짜 최댓값이 되고
5 6 7 같은 경우 최댓값 18, 최솟값 5
이 경우 빼게 되면 오히려 값이 줄어든다. 이때는 빼지 않고 최댓값만 반환한다.
🔅 문제 풀이
class Solution {
public long solution(int[] sequence) {
long answer = 0;
long[] pulse1 = {1, -1};
long[] pulse2 = {-1, 1};
long min = Long.MAX_VALUE;
long max = Long.MIN_VALUE;
answer = Math.max(answer, calcPartSequenceSum(sequence, pulse1, min, max));
answer = Math.max(answer, calcPartSequenceSum(sequence, pulse2, min, max));
return answer;
}
private long calcPartSequenceSum(int[] sequence, long[] pulse, long min, long max) {
long sum = 0;
for (int i = 0; i < sequence.length; i++) {
sum += sequence[i] * pulse[i % 2];
min = Math.min(min, sum);
max = Math.max(max, sum);
}
// min을 뺐을때와 안뺐을때 둘중 가장 큰 것을 고려
if (max - min < max) {
return max;
}
return max - min;
}
}

❗ 오답노트 / 필요한 지식
- 반성하게 된다. 정말..