https://school.programmers.co.kr/learn/courses/30/lessons/42860
위 아래로 진행하는 것과 좌우로 이동하는 것을 나눠서 계산을 진행하였습니다.
먼저 진행전에 A로만 이루어졌는지 체크를 통해서 A만 있는경우 빠르게 0을 리턴해서 끝내줍니다.
그후 nameCost를 통해서 각 문자에 대해서 최소한의 이동을 체크하고
moveCast를 통해서 최소이동을 체크해서 각 값을 더해줍니다.
문자 위 아래 이동은 A에서 시작했을 경우와 Z로올라가서 역순으로 체크하는 경우 2가지 경우중에 최소의 값을 가져옵니다.
여기에서 가장 큰 문제가 발생했는데
이동 횟수를 체크할 때
이 4가지 방법을 어떻게 해야할지 감이 잘 안잡혀서 다른 블로그를 통해서 이해하고 적용시켰습니다.
A가 연속적으로 몇개가 나오는 지 체크하고
앞으로 갔다가 뒤로 가는경우와 뒤로 갔다가 앞으로 가는경우와 정방향으로 갔을경우의 최소이동을 계산해서 값을 리턴해준다.
//이동부분 참고 블로그
Greedy
class Solution
{
public int solution(String name) {
int move_up_down = 0;
//A면서 name의 길이가 1인경우
if(name.charAt(0) == 'A' && name.length() == 1)
return 0;
//전부 A인지 체크
boolean isAllA = true;
for(int idx =0; idx <name.length();idx++){
if(name.charAt(idx) != 'A')
isAllA = false;
if(!isAllA)
break;
}
if(isAllA)
return 0;
return nameCost(name) + moveCost(name);
}
//이름 체크용
private int nameCost(String name) {
int move_up_down =0;
//전체에서 각 문자에 대해서 문자 변경이 진행되는 경우
for(int idx = 0; idx <name.length();idx++){
char ch = name.charAt(idx);
//A에서 시작하거나 역순으로 이동했을경우 둘중 작은놈으로
move_up_down += Math.min(ch - 'A','Z' - ch + 1);
System.out.println("index = " + idx + "번째 문자" +name.charAt(idx) + " " + move_up_down);
}
return move_up_down;
}
//이동 횟수 체크
// 생각해야할점 : 뒷부분이 전부 A이면 횟수를 체크할 필요가없음.
// 연속적인 A가 몇개인지 알아야함.
//1. 처음부터 끝까지 정순이동
//앞으로 갔다가 뒤로 가는경우
//앞으로 갔다가 뒤로 가는경우
private int moveCost(String name) {
//정방향 이동
int move = name.length() -1;
for(int idx = 0; idx < name.length();idx++){
int index = idx+1;
while(index < name.length() && name.charAt(index)== 'A'){
index+=1;
}
//앞으로 갔다가 뒤로 가는경우
move = Math.min(move,2*idx + name.length() - index);
//앞으로 갔다가 뒤로 가는경우
move = Math.min(move,idx + (name.length()-index)*2);
}
return move;
}
}