본문 바로가기
Algorithme/Programmers

[프로그래머스] 방문길이 Java

by 케로베로 2020. 10. 29.

 

programmers.co.kr/learn/courses/30/lessons/49994

 

코딩테스트 연습 - 방문 길이

 

programmers.co.kr

 

문제 요약

 x좌표와 y좌표가 각각 -5에서부터 5까지 있는 좌표평면이 있다. 게임 캐릭터는 (0, 0)부터 시작하여서 U, D, L, R 각각의 문자마다 위로, 아래로, 왼쪽으로, 오른쪽으로 이동한다. 이동문자가 여러개 있는 문자열을 받아서 그대로 이동할 때 이동의 개수를 중복된 길을 제외하고 반환해야 한다.

 

문제 풀이

 "중복되지 않고" 라는 조건만 보아도 Set으로 푸는 문제임을 알 수 있다. 나는 이동방향, 현재 x좌표, 현재 y좌표로 문자열을 만들어서 문자열에 Set에 넣기로 정했다.

 

 문자열 dirs을 반복문을 통해 한자리 씩 커맨드를 받고 그대로 이동할 것인데 우선 경로밖을 벗어나는 문자를 받은 경우에는 무시처리했다. 위에 말한대로 문자열을 만들어서 set에 add하는데 그 뿐만이아니라 반대편에서 부터 현재로 오는 문자열 또한 add 해줘야 한다. U00과 D01은 경로가 같기 때문이다. 명령 당 set에 2개의 문자열을 넣고 해당방향으로 좌표를 옮기는 것을 반복한다. 마지막에는 Set의 크기 2로 나누어서 캐릭터가 처음 지나간 길의 개수를 알 수가 있다.

 

 그리고 문자열을 만들 때 처음에는 우선 '+'로 더하여서 만들었고, 정답 처리를 받은 후 concat을 사용하는 방법으로 바꿔주었다. 그결과 처리 성능이 10배에서 크게는 200배까지도 좋아졌다. 역시 문자열을 처리할 때 '+'는 절대 사용하지 말아야 할 방법이라는 것을 다시 한번 느꼈다.

 

나의 코드

import java.util.HashSet;
import java.util.Set;

class 방문_길이 {
    public int solution(String dirs) {
        int x = 0;  //  현재 위치 x축
        int y = 0;  //  현재 위치 y축
        Set<String> set = new HashSet<>();  //  이동을 담을 Set

        /* 이동 시작 */
        for (int i = 0; i < dirs.length(); ++i) {
            char dir = dirs.charAt(i);

            // 판을 벗어나려는 명령은 무효
            if ((y == 5 && dir == 'U') || (y == -5 && dir == 'D') || (x == 5 && dir == 'R') || (x == -5 && dir == 'L'))
                continue;

            // 이동 명령과 현재 위치를 set 에 넣기
            set.add("".concat(String.valueOf(dir)).concat(String.valueOf(x)).concat(String.valueOf(y)));

            // 반대로 도착지 -> 출발지 또한 set 에 넣기
            if (dir == 'U') {
                set.add("D".concat(String.valueOf(x)).concat(String.valueOf(y + 1)));
                y++;
            } else if (dir == 'D') {
                set.add("U".concat(String.valueOf(x)).concat(String.valueOf(y - 1)));
                y--;
            } else if (dir == 'R') {
                set.add("L".concat(String.valueOf(x + 1)).concat(String.valueOf(y)));
                x++;
            } else if (dir == 'L') {
                set.add("R".concat(String.valueOf(x - 1)).concat(String.valueOf(y)));
                x--;
            }
        }

        return set.size() / 2;
    }
}