오락실에서 마지막에 하던 이니셜 세기는 것과 비슷하다고 생각하면 된다. 아파벳 뿐만아니라 자리도 역순으로 돌 수 있다.
위로 올리면 정순, 아래로 내리면 역순으로 알파벳을 바꿀 수 있다. 최소한으로 움직여야 하므로 정순과 역순중 빠른 걸 고르면 될것이다.
answer += Math.min(name.charAt(i) - 'A','Z'-name.charAt(i) + 1);
name.charAt(i) - 'A'
는 정순, 'Z' - name.charAt(i)
는 역순으로 둘중 최소값을 골라 answer에 추가한다.
오른쪽은 다음자리, 왼쪽은 이전자리, 왼쪽끝에서 왼쪽은 마지막, 오른쪽끝에서 오른쪽은 처음으로 이동 가능하다.
예시처럼JAZ
는 J
A
Z
순 보단 J
Z
순으로만 수정하면 완성할 수 있으므로 자리수도 고려 되어야 한다.
A
를 주목 하여야 한다. A
는 알파벳을 수정하지 않고 그냥 지나쳐도 무관하고 가본적이 없어도 완성 가능하다.
A
가 앞으로 몇개나올 것인지 계산후 정순과 돌아가서 마지막으로 이동하는 것 중 최소를 고르면 된다.
index = i + 1; while(index < length && name.charAt(index) == 'A') index++;
현재위치에서 A가 몇개 연속되는지 구하는 while문이다.
A가 나올동안 index는 1씩 증가하므로 index는 연속된 A의 다음 문자의 위치를 가리키게 될것이다.
move = Math.min(move,i * 2 + length-index);
정순 길이와 왔던 길을 돌아서 A가 끝나는 다음 위치로 이동하는 길를 비교.
move = Math.min(move,(length-index)* 2 + i);
위의 비교와 같이 역순으로 구하다 돌아와서 연속된 A의 시작전으로 돌아오는 비교.
class Solution {
public int solution(String name) {
int alpha = 0;
int length = name.length(); //이름의 길이
int index;
int move = length - 1; //이동 길이
for(int i = 0; i < length; i++){
//알파벳 순, 역 중에 작은 값
alpha += Math.min(name.charAt(i) - 'A','Z'-name.charAt(i) + 1);
//A가 연속되면 조작할 필요가 없으므로 A가 끝나는 다음 지점 위치를 구함
index = i + 1;
while(index < length && name.charAt(index) == 'A') index++;
move = Math.min(move, i * 2 + length - index); //순방향 -> 역방향 자리 이동 경우
move = Math.min(move, (length-index) * 2 + i); //역방향 -> 순방향 자리 이동 경우
}
//알파벳 조작 + 자리 조작
return alpha + move;
}
}