본문 바로가기
코딩 테스트/[JAVA] programmers 코딩 테스트 연습

[Programmers/JAVA] 방문 길이 / 프로그래머스 코딩 테스트 연습

by M개발자 2021. 12. 31.
반응형

방문 길이

 


문제 설명

 

게임 캐릭터를 4가지 명령어를 통해 움직이려 합니다. 명령어는 다음과 같습니다.

  • U: 위쪽으로 한 칸 가기
  • D: 아래쪽으로 한 칸 가기
  • R: 오른쪽으로 한 칸 가기
  • L: 왼쪽으로 한 칸 가기

캐릭터는 좌표평면의 (0, 0) 위치에서 시작합니다. 좌표평면의 경계는 왼쪽 위(-5, 5), 왼쪽 아래(-5, -5), 오른쪽 위(5, 5), 오른쪽 아래(5, -5)로 이루어져 있습니다.

명령어가 매개변수 dirs로 주어질 때, 게임 캐릭터가 처음 걸어본 길의 길이를 구하여 return 하는 solution 함수를 완성해 주세요.


예시

 

 

dirs answer
"ULURRDLLU" 7
"LULLLLLLU" 7

코드 해석 및 전체 코드

 

1. 좌표 변수 선언 (int x, int y)

2. dirs 길이만큼 for문 반복

3. dirs문자열 i번째와 일치하는 이동방향에 해당하는 좌표 +-

4. 현재 위치 + 이동한 위치 문자열 선언

5. 이동한 위치 + 현재 위치 문자열 선언

6. 이미 ArrayList에 값이 존재하거나 4, 5번이 같을 경우 저장하지 않음

7. for문 반복이 끝나면 visit의 사이즈 / 2한 값 반환 

 

좌표 이동

처음 위치 (0, 0)

U일 경우 y좌표를 1 증가 시킴, y의 최댓값은 5이므로 5미만일 때만 증가 가능

D일 경우 y좌표를 1 감소 시킴, y의 최솟값은 -5이므로 -5초과일 때만 감소 가능

R일 경우 x좌표를 1 증가 시킴, x의 최댓값은 5이므로 5미만일 때만 증가 가능

L일 경우 x좌표를 1 감소 시킴, x의 최솟값은 -5이므로 -5초과일 때만 감소 가능

 

            if (s == 'U' && y < 5) y++;
            else if (s == 'D' && y > -5) y--;
            else if (s == 'R' && x < 5) x++;
            else if (s == 'L' && x > -5) x--;

 

방문 중복 체크

중복된 이동일 경우 반환값을 증가하지 않음. 중복값 체크를 위해 ArrayList를 선언하고

현재 좌표 + 이동 좌표, 이동 좌표 + 현재 좌표의 값을 저장

현재 좌표 + 이동 좌표만 저장하면 이동 좌표 → 현재 좌표로 이동한 것은 새로운 이동이라 볼 수 있기에

현재 → 이동과 이동 → 현재 경우를 모두 저장함.

 

한 가지 더 체크해야하는데, 범위를 벗어나게 되면 좌표의 현재 좌표는 (5, 5), 이동 좌표도 (5, 5)가 됨. 이 경우는 이동한 것이 아니므로 반환값에 더해지면 안됨. 그래서 현재 좌표와 이동 좌표가 같은지도 체크해야 함

            if (!visit.contains(st) && !visit.contains(nd) && !st.equals(nd)) {
                visit.add(st);
                visit.add(nd);
            }

 

여담 ( 시간 단축 )

더보기

int형에서 String형으로 형변환 하는 과정에서 시간이 꽤 소비되는게 찝찝해서 별별 짓을 다 해 보았다.

 

방법 1

처음 시도했던 방법은 가장 기본적인 방법으로 Integer.toString() 메소드를 사용해서 x를 먼저 형변환한 뒤 y를 붙이는 방법이었다.

왜 가장 기본적이냐...? int to String을 검색했을 때 제일 먼저 나오는 메소드이기에... 가장 기본적인 방법이라 생각했다. 

시간대는 1.XXms ~ 5.XXmx로 0.XXms가 나오지 않아 다른 방법을 시도해보았다. 

            String xy = Integer.toString(x);
            xy += Integer.toString(y);
            String reXY = Integer.toString(reX);
            reXY += Integer.toString(reY);
            String st = xy + reXY;
            String nd = reXY + xy;

 

방법 2

두번째 시도했던 방법은 다른 사람의 풀이에서 많이 볼 수 있던 방법으로 숫자를 더하면서 중간에 ""을 넣어 문자열로 만들어주는 방법이다.

오 이렇게 간단하게 ~~ 라는 생각으로 바꿔보았는데.... 12초.....???라니...... 

            String st = x+""+y+""+reX+""+reY;
            String ed = reX+""+reY+""+x+""+y;

 

방법 3

두 번째 방법으로 시간이 단출될 줄 알고 이전 코드를 날렸는데 대실패라서 코드를 다시 짜야했었다.

그래서 1번 방법과 유사하면서 간단하게 짰는데... 웬걸..~~ 이렇게 해도 시간이 꽤 나왔다.

            String xy = Integer.toString(x) + y;
            String reXY = Integer.toString(reX) + reY;
            String st = xy+reXY;
            String nd = reXY + xy;

 

결국... 첫번째 방법으로 돌아갔다... 1초면 꽤 선빵... ㅎㅎ

점수도 1점 나올 줄 알았는데 7점인가 11점인가 나옴

 

import java.util.ArrayList;

class Solution {
    public int solution(String dirs) {
        int answer = 0;
        int x = 0;
        int y = 0;
        ArrayList<String> visit = new ArrayList<String>();
        
        //dir 길이만큼  for문 반복
        for (int i = 0; i < dirs.length(); i++) {
        	//현재 x, y 좌표를 초깃값으로 갖는 변수 선언
            int reX = x;
            int reY = y;
            // dirs i번째 문자 가져오기
            char s = dirs.charAt(i);
            
            // s와 범위 체크하고 해당하는 좌표 +-
            if (s == 'U' && y < 5)
                y++;
            else if (s == 'D' && y > -5)
                y--;
            else if (s == 'R' && x < 5)
                x++;
            else if (s == 'L' && x > -5)
                x--;

            // arrayList에 저장할 변수 선언
            // st = x + y + reX + reY
            // nd = reX + reY + x + y
            String xy = Integer.toString(x);
            xy += Integer.toString(y);
            String reXY = Integer.toString(reX);
            reXY += Integer.toString(reY);
            String st = xy + reXY;
            String nd = reXY + xy;
            
            // visit에 존재하지 않고 st와 ed가 같지 않으면 visit에 add
            if (!visit.contains(st) && !visit.contains(nd) && !st.equals(nd)) {
                visit.add(st);
                visit.add(nd);
            }

        }
        
        // 이동 한 번에 2개의 값을 저장했으므로 /2한 값 반환
        answer = visit.size() / 2;
        return answer;
    }
}

github

programmers

 

반응형

댓글