문제를 두 가지로 나눠보자.
- 조이스틱 상, 하 조작
- 조이스틱 좌, 우 조작
상, 하 조작의 경우에는 아래로 조작하는 경우와 위로 조작하는 경우 중 최소 값을 찾으면 된다.
→ Math.min((name.charAt(i) - 'A'), ('Z' - name.charAt(i) + 1))
좌, 우 조작의 경우에는 다음 3가지로 커서가 변경될 수 있다.
따라서 좌우 로직은 다음 3가지의 경우 중, 최소값을 선택하여 이동하면 된다.
즉, 오른쪽으로 쭉 가는 경우를 최악의 경우라 생각하고, 왼쪽에서 오른쪽 오른쪽에서 왼쪽으로 이동할 수 있는 경우를 체크하는 것!
※ 이때 이동한다는 의미는 상, 하 조작은 자동적으로 수행되고 A가 아닌 부분을 어떻게 거쳐가는 지를 의미한다.
class Solution {
public int solution(String name) {
int answer = 0;
int move = name.length() - 1; // 오른쪽으로만 쭉 이동하는 횟수
// 위아래 조작 횟수 계산
int[] control = new int[name.length()];
for(int i=0; i<name.length(); i++) {
control[i] = Math.min((name.charAt(i) - 'A'), ('Z' - name.charAt(i) + 1));
}
// 좌우 조작
for(int i=0; i<name.length(); i++) {
answer += control[i];
if(i < name.length() - 1 && control[i+1] == 0) {
int endA = i + 1;
while(endA < name.length() && control[endA] == 0)
endA++;
move = Math.min(move, i*2 + (name.length() - endA)); // 오른쪽 -> 왼쪽
move = Math.min(move, i + (name.length() - endA) * 2); // 왼쪽 -> 오른쪽
}
}
return answer + move;
}
}