일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 인텔리제이
- 구름LEVEL
- HTTP
- 문자열
- 주니어
- 백엔드
- IntelliJ
- spring
- 스타트업
- docker
- 명령어
- 개발자
- 스프링 부트
- 프로그래머스
- 도커
- 해결
- 이직
- 코딩테스트
- bfs
- 배열
- dfs
- spring boot
- 자료구조
- 구현
- Java
- 해시맵
- Linux
- HashMap
- 스프링
- 스프링부트
- Today
- Total
마이의 개발 블로그
[프로그래머스] 공원 산책 (Java) 본문
접근 방식
단순 구현 문제로 금방 해결할 줄 알았으나 케이스 예외처리를 제대로 해주지 못해 애를 먹었던 문제이다. 문제에도 적혀있듯 이동 명령을 수행하며 범위를 벗어나는지 여부와 지도에서 'X'로 막혀있는지 여부의 두 가지 조건만 체크하면 되는 문제인데, 동서남북 각 방향에 따른 예외 처리와 반복문 처리가 각각 달라 길게 작성된 코드를 짧게 처리하는데 애를 먹었다. 더 짧게 하고싶은데 다른 사람들 코드도 길이가 비슷한 걸 보니 어쩔 수 없는 문제였던 것 같기도 하다.
로직 설명
- 시작점 찾기: 문자열 "S"를 포함한 문자열의 x값, y값 저장
- routes 배열의 각 이동명령 move를 탐색하며:
1) move로부터 방향(dir)과 숫자(num) 추출하기
2) 서, 북인 경우 num에 -1 곱하기
3) 동, 서인 경우 x축 이동, 남, 북인 경우 y축 이동한 값을 postX, postY 변수에 저장하기 (기존 x, y는 변화없음)
4) 조건1: 지도 범위를 벗어난 경우 명령 무시 (continue)
5) 조건2: 이동할 경로에 'X'표가 있는 경우 명령 무시. x와 postX, y와 postY 간의 경로를 탐색하며 'X'표시가 있는 경우 isBlocked = true 표기 후 루프 종료 (x축과 y축은 각각 다른 루프로 체크)
6) 장애물이 없으면(isBlocked가 false이면) x와 y에 각각 postX, postY 대입하기
- 결과 반환 (y, x 순으로 배열 생성)
Note
- 주의해야할 점은 x와 postX, y와 postY 사이의 경로를 탐색함에 있어 기존과 post 둘 중 어떤 숫자가 더 크냐에 따라 루프의 시작점이 달라져야한다는 점이다. 이 부분을 캐치하지 못해 몇몇 케이스에서 오류가 났고 결국 두 개의 루프문 안에 삼항연산자를 사용해 매번 작은 값부터 큰 값으로 경로가 이동하도록 했다. 그러나 이렇게 처리할 경우 굳이 체크 안 해도 되는 시작 좌표를 한 번 더 점검하게 될 수도 있는 단점이 있는데 코드 몇 줄 늘리는 것보단 가독성이 더 나을 것 같아 그대로 두기로 했다.
class Solution {
public int[] solution(String[] park, String[] routes) {
int x = 0, y = 0;
for(String str: park){
if(str.contains("S")){
x = str.indexOf("S");
break;
}
y++;
}
for(String move : routes){
String[] arr = move.split(" ");
Character dir = arr[0].charAt(0);
int num = Integer.parseInt(arr[1]);
int postX = x, postY = y;
num *= (dir == 'W' || dir == 'N') ? -1 : 1;
if(dir == 'E' || dir == 'W'){
postX += num;
}else{
postY += num;
}
if(postX < 0 || postX >= park[0].length() || postY < 0 || postY >= park.length){
continue;
}
Boolean isBlocked = false;
for(int i = (x < postX ? x : postX); i <= (x < postX ? postX : x); i++){
if(park[y].charAt(i) == 'X'){
isBlocked = true;
break;
}
}
for(int j = (y < postY ? y : postY); j <= (y < postY ? postY : y); j++){
if(park[j].charAt(x) == 'X'){
isBlocked = true;
break;
}
}
if(!isBlocked){
x = postX;
y = postY;
}
}
return new int[] {y, x};
}
}
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 교점에 별 만들기 (Java) (0) | 2023.05.28 |
---|---|
[프로그래머스] 점 찍기 (Java) (0) | 2023.05.28 |
[프로그래머스] 추억 점수 (Java) (0) | 2023.04.20 |
[프로그래머스] 택배상자 (Java) (0) | 2023.04.20 |
[프로그래머스] 다항식 더하기 (Java) (0) | 2023.04.19 |