본문 바로가기

문제 풀이/Programmers

[프로그래머스] 조이스틱 (JAVA)

문제 출처 - Programmers

문제는 여기

 

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr


[풀이]

1. 이름이 모두 A로만 구성이 되었을 경우, 단순히 이동만 하면 되므로 글자의 길이가 최솟값이 된다.

2. 이름을 만들기 위해 상하로 움직이는 경우를 구해준다.

3. 이름 중 A가 연속된 구간이 있다면 해당 부분은 좌우 이동만 해줄 수 있으므로 좌우 이동을 해 더 적은 횟수가 나오는 방법을 구해준다.

4. 결과를 출력해준다.

[접근]

1. 문제를 이해하지 못해서 다른 사람들의 글을 참조한 문제이다.

2. 단순히 횟수를 증가시키며 오른쪽으로 이동하는 방법과 좌우 이동을 해서 글자를 바꾸고 위치를 이동하는 방법을 비교하는 문제였다.

커서 위치가 바뀌게 되는 경우는 총 세 가지이다.
1. 처음부터 쭉 오른쪽으로 가는 경우
    가장 일반적인 경우로 name.length() - 1로 해당한다.
2. 오른쪽으로 갔다 다시 리턴하여 왼쪽으로 가는 경우
    ex) ZZAAZZZ 의 경우, 앞에서 ZZ까지 갔다가 다시 돌아가 ZZZ를 완성해준다.
3. 왼쪽으로 갔다 다시 리턴하여 오른쪽으로 가는 경우
    ex) ZZZAAAZ 의 경우, 처음부터 왼쪽으로 움직여 마지막에 있는 Z를 완성해주고
    다시 오른쪽으로 돌아가 ZZZ를 완성해준다.

[코드]

class Solution {
    public int solution(String name) {
        int answer = 0;
        int len = name.length();

        // 단순 이동만 하는 경우
        int min = len - 1;

        for (int i = 0; i < len; i++) {
            char c = name.charAt(i);
            // 조이스틱 상, 하 이동
            int mov = (c - 'A' < 'Z' - c + 1) ? (c - 'A') : ('Z' - c + 1);
            
            answer += mov;

            // 조이스틱 좌, 우 이동
            int idx = i + 1;
            // 이름에 A가 들어가면 기본 값으로 넘어가면 되므로
            // 인덱스 값만 증가
            while (idx < len && name.charAt(idx) == 'A')
                idx++;

            // 그냥 이동하는 경우
            // 현재 위치에서 오른쪽으로 이동 후 글자를 바꾸고 다시 돌아오는 경우
            // 현재 위치에서 왼쪽으로 이동 후 글자를 바꾸고 다시 돌아오는 경우
            min = Math.min(min, Math.min((i * 2) + len - idx, (len - idx) * 2 + i));
        }

        answer += min;
        
        return answer;
    }
}