728x90
아이디어
먼저 이 문제는
- 알파벳을 업데이트 하는 것과
- 이동하는 것
두 가지로 쪼갤 수 있다.
알파벳 업데이트
알파벳을 업데이트 하는 것은 단순히 A로부터 현재 알파벳에 도달하는 격차
와,Z로부터 현재 알파벳에 도달하는 격차 + 1
중 더 작은 것을 선택하면 된다.
이동
틀린 풀이
이동하는 것이 문제인데, 처음에는 잘못 생각해서 다음과 같이 풀이를 했었다.
- 현재 위치를 0으로 잡고 왼쪽, 오른쪽 거리를 매긴다
- 왼쪽에서 가장 가까운 Not A, 오른쪽에서 가장 가까운 Not A 간의 거리를 비교한다
- 더 가까운 쪽을 선택하여 현재 위치를 업데이트하고, Not A인 알파벳의 갯수를 감소시킨다.
만약 Not A인 알파벳 갯수가 0이라면 종료. 종료 전까지 1 ~ 3 반복
나머지 예제는 전부 맞았지만, 예제 3번에서 오답이 나왔다.
"BBBBAAAABA"
이 같은 경우에 나의 초기 풀이대로 풀게 되면 13이 나오지만 정답은 12이다.
단순히 가까운 쪽을 그때 그때 선택하는 것보다, 왼쪽으로 갔다가 오른쪽으로 다시 돌아오는 쪽이 더 효율적인 경우이다.
위와 같이 A가 여러 개 뭉쳐있을 때는 초기 풀이를 적용할 수 없다.
맞는 풀이
현재 인덱스에서 A가 연속해서 있는 경우, 연속된 A가 끝나는 지점까지를 계산
1. 단순히 오른쪽으로 계속 이동하게 됐을 때 len - 1 번 이동 = 최댓값
2. 시작점에서 오른쪽으로 이동했다가 다시 왼쪽으로 가는 경우 = i * 2 + (len - endA)
3. 시작점에서 왼쪽으로 이동했다가 다시 오른쪽으로 가는 경우 = (len - endA) * 2 + i
3개 값 중 최소값이 이동 횟수가 된다.
import java.util.*;
class Solution {
public int solution(String name) {
int answer = 0, len = name.length(), move = len - 1;
for(int i = 0; i < len; i++) {
answer += Math.min(name.charAt(i) - 'A', Math.abs(name.charAt(i) - 'Z') + 1);
if(i + 1 < len && name.charAt(i + 1) == 'A'){
int endA = i + 1;
while(endA < len && name.charAt(endA) == 'A') endA++;
move = Math.min(move, Math.min(i * 2 + (len - endA), i + (len - endA) * 2));
}
}
return answer + move;
}
}
728x90
'알고리즘' 카테고리의 다른 글
프로그래머스 - 구명보트 (Java, 투포인터) (0) | 2025.03.05 |
---|---|
프로그래머스 - 큰 수 만들기 (Java, 그리디) (0) | 2025.03.05 |
프로그래머스 - 전력망을 둘로 나누기 (Java, 완전 탐색, bfs) (0) | 2025.03.05 |
프로그래머스 - 소수 찾기 (Java, 백트래킹, 소수, 에라토스테네스의 체) (0) | 2025.03.04 |
프로그래머스 - 이중우선순위큐 (Java) (0) | 2025.03.04 |