코딩테스트
[ 프로그래머스 ] 방문 길이
Adose
2024. 12. 5. 13:52
📌요구 사항 정리
- 게임 캐릭터가 지나간 길 중 캐릭터가 처음 걸어본 길이를 구해야 한다.
- 중복 경로는 최종 길이에 포함하지 않는다.
📌 제약 조건
- 문자형으로 주어지며, U, D, R, L 이외의 문자는 주어지지 않는다.
- 길이는 500이하의 자연수이다.
📌 첫번째 풀이 문제 분석 ( 실패 )
❓ 처음 문제를 풀때, 그래프 생각을 못하고 단순히 방문 안했으면 0, 방문하면 1 이런식으로 했다.
하지만 이런식으로 구현하면 좌표 이동이 아닌, 그냥 좌표만 확인할 수 있으므로 좌표 이동을 확인할 수 없다.
예를들어 5,5 에서 Up을 하면 5,5 → 4,5 이게 1 이런식으로 되어야 하는데 단순히 좌표 위치를 0으로 선언하니까
Up 해야 할때 5,5 아니면 4.5 하나만 1(방문확인)로 변경이 된다.
—> 계속 해보다가 잘못됨을 느끼고 그래프로 다시 구현 했다.
- 아래는 잘못된 문제 분석
- 표 사이즈는 -5 ~ 5 이기 때문에, 10 사이즈의 표를 만들어야 한다.
- 표는 0으로 초기화하고, 해당 위치를 방문하게 되면 1로 변경해준다.
- 해당되는 방향으로 이동한다.
- 표의 값이 0이라면, 방문길이 +1 을 해주고 1이라면 넘긴다.
- 방향 마다의 정보를 배열에 저장해야한다.
- 현재 위치를 나타내는 정보를 배열에 저장해야한다.
❗ 실패 코드
public int solution(String dirs) {
char[] direction = dirs.toCharArray();
int[][] gameBoard = new int[10][10];
int[] currentLocation = {5, 5};
int gameLength = 0;
for (char location : direction) {
int[] countLocation = getDirectionIfo(location);
int newNum = currentLocation[0] + countLocation[0];
int colNum = currentLocation[1] + countLocation[1];
// 경계를 벗어나면 무시
if (newNum < 0 || newNum >= 10 || colNum < 0 || colNum >= 10) {
continue;
}
// 새로운 위치 방문 여부 확인
if (gameBoard[newNum][colNum] == 0) {
gameBoard[newNum][colNum] = 1;
gameLength += 1;
}
// 현재 위치 갱신
currentLocation[0] = newNum;
currentLocation[1] = colNum;
}
return gameLength;
}
public int[] getDirectionIfo(char dir) {
Map<Character, int[]> directionInfo = new HashMap<>();
final int[] U = {-1, 0};
final int[] R = {0, 1};
final int[] L = {0, -1};
final int[] D = {1, 0};
directionInfo.put('U', U);
directionInfo.put('R', R);
directionInfo.put('L', L);
directionInfo.put('D', D);
return directionInfo.get(dir);
}
📌 두번째 풀이 문제 분석 ( 성공 )
- HashSet<int [] > 를 사용하지 않는이유
- HashSet은 배열의 참조를 비교하고, 값에는 참조하고 있지 않기 때문에 구분을 할 수 없다.
- 현재 위치를 나타낼 수 있는 좌표를 저장해야한다.
- HashSet을 사용하여 중복을 허락하지 않고, x,y -> nx, ny 와 nx,ny -> x ,y 으로 저장할 수 있도록 한다.
- x,y -> nx, ny 와 nx,ny -> x ,y 으로 하면 A -> B, B -> A 경로를 둘다 저장하여, 같던 길을 다시 갈 수 없도록 한다.
- 만약 설정한 범위 -5 ~ 5 를 넘는다면 넘기도록 한다. 좌표가 유효하지 않으면 경로 활동(=계산)에 추가하지 않는다.
private static final HashMap<Character, int[]> direction = new HashMap<>();
public int solution(String dirs) {
setDirectionIfo();
char[] playerDirection = dirs.toCharArray();
int x = 5;
int y = 5;
HashSet<int[]> gameLength = new HashSet<>();
for (char location : playerDirection) {
int offset[] = direction.get(location);
int nx = x + offset[0];
int ny = y + offset[1];
if (validArea(nx, ny)) {
continue;
}
gameLength.add(new int[]{x, y, nx, ny});
gameLength.add(new int[]{nx, ny, x, y});
x = nx;
y = ny;
}
return gameLength.size() / 2;
}
private void setDirectionIfo() {
direction.put('U', new int[]{-1, 0});
direction.put('D', new int[]{1, 0});
direction.put('R', new int[]{0, 1});
direction.put('L', new int[]{0, -1});
}
private boolean validArea(int x, int y) {
if (x < 0 || x > 10 || y < 0 || y > 10) {
return true;
}
return false;
}