class Solution {
public int solution(String name) {
int answer = 0;
int move = name.length() - 1; // 정방향으로 움직였을 때는 글자 길이의 -1 만큼 움직인다.
char[] chars = name.toCharArray();
for (int i = 0; i < chars.length; i++) {
// 알파벳 변형에 얼마나 비용이 필요한가? 를 계산
answer += getChangeCnt(chars[i]);
// 해당 인덱스 뒤로 만약에 A가 연속적으로 있다면 그만큼 개수를 세어준다.
int idx = i + 1;
while (idx < chars.length && chars[idx] == 'A') {
idx += 1;
}
move = Math.min(move, i * 2 + chars.length - idx); // 앞에서부터 돌고 그 다음에 뒤로가는게 더 적은 움직임을 갖게되는 경우 (BBAAABBB)
move = Math.min(move, i + (chars.length - idx) * 2); // 뒤에서부터 돌고 다시 돌아오는 경우가 더 적은 움직임을 갖게되는 경우 (BBBAAABB)
}
return answer + move;
}
// 상하로 움직이는 경우 (알파벳을 바꿀떄 필요)
public int getChangeCnt(char a) {
return Math.min(a - 'A', 'Z' - a + 1);
}
}
현재 문자 - 'A'
'Z' - a + 1
이다.◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
BBAAABB
라고 주어진다면 가장 최소 탐색법은 다음과 같다. (이동만 따진다. 알파벳 변경은 위에서 처리한다)문자열의 길이 - 1
로 6번이지만, 위처럼 이동시에는 4번만 이동하면 된다.현재 인덱스 * 2 // 연속된 A를 만나기 전에 한번 왔다가 갔다가 하는 경우의 수
+ (전체 문자열 길이 - 마지막 연속된 A까지의 문자 길이) // 마지막으로 연속된 A 까지의 문자열을 제외한 나머지 이동거리
현재 인덱스 // 연속된 A를 만나기전에 이동하는 경우의 수
+ (전체 문자열 길이 - 마지막 연속된 A까지의 문자의 길이) * 2 // 마지막으로 연속된 A 까지의 문자열을 제외한 나머지 문자열 왔다 갔다하는 경우의 수