99클럽 코테 스터디 35일차 게임 맵 최단거리

2024. 8. 25. 16:46·스터디/99클럽 코테 스터디 TIL

📝 문제

 
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

🔥 시도해본 접근 방식

1. 주어진 행렬을 통해 재귀 DFS을 사용

2. 목표지점까지 이동 할 수 있는 모든 경우의 수 들의 이동 칸수를 리스트에 기록하여 최소값을 답으로 반환

위와 같은 방법으로 접근하였다.

 

1️⃣ 첫번째 시도

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Solution {
    int[][] maps;
    boolean[][] visited;

    int rowSize;
    int columnSize;

    // 목표 지점에 도달 가능한 루트의 이동한 칸 수 리스트
    List<Integer> cntList;

    // 상, 하, 좌, 우
    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};

    public int solution(int[][] maps) {
        this.maps = maps;
        this.rowSize = maps.length;
        this.columnSize = maps[0].length;
        this.visited = new boolean[this.rowSize][this.columnSize];
        this.cntList = new ArrayList<>();

        recursiveDfs(0, 0, 0);

        Collections.sort(this.cntList);

        if (this.cntList.isEmpty()) {
            return -1;
        } else {
            return this.cntList.get(0);
        }
    }

    private void recursiveDfs(int x, int y, int cnt) {
        cnt++;
        this.visited[x][y] = true;

        // x와 y가 마지막 목표지점에 도달했다면 list에 이동한 칸수 기록
        if (x == this.rowSize - 1 && y == this.columnSize - 1) {
            this.cntList.add(cnt);
            return;
        }

        // 현재 위치에서 이동 가능한 방향으로 이동
        for (int i = 0; i < 4; i++) {
            int nextX = x + this.dx[i];
            int nextY = y + this.dy[i];

            if (nextX >= 0 &&
                    nextX <= this.rowSize - 1 &&
                    nextY >= 0 &&
                    nextY <= this.columnSize - 1 &&
                    this.maps[nextX][nextY] == 1 &&
                    !this.visited[nextX][nextY]
            ) {
                recursiveDfs(nextX, nextY, cnt);
            }
        }
    }
}

위와 같이 작성하여 제출 하였지만 여러 케이스에서 실패 하였다.

자세히 보니 위 코드에서는 visited 배열의 원소 값이 재귀호출에서 돌아오는 경우 원소의 상태를 복구하지 않고 있는 결함을 발견하였고,

백트래킹 처리를 추가하였다.

2️⃣ 두번째 시도

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Solution {
    int[][] maps;
    boolean[][] visited;

    int rowSize;
    int columnSize;

    // 목표 지점에 도달 가능한 루트의 이동한 칸 수 리스트
    List<Integer> cntList;

    // 상, 하, 좌, 우
    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};

    public int solution(int[][] maps) {
        this.maps = maps;
        this.rowSize = maps.length;
        this.columnSize = maps[0].length;
        this.visited = new boolean[this.rowSize][this.columnSize];
        this.cntList = new ArrayList<>();

        recursiveDfs(0, 0, 0);

        Collections.sort(this.cntList);

        if (this.cntList.isEmpty()) {
            return -1;
        } else {
            return this.cntList.get(0);
        }
    }

    private void recursiveDfs(int x, int y, int cnt) {
        cnt++;
        this.visited[x][y] = true;

        // x와 y가 마지막 목표지점에 도달했다면 list에 이동한 칸수 기록
        if (x == this.rowSize - 1 && y == this.columnSize - 1) {
            this.cntList.add(cnt);
            this.visited[x][y] = false; // 백트래킹
            return;
        }

        // 현재 위치에서 이동 가능한 방향으로 이동
        for (int i = 0; i < 4; i++) {
            int nextX = x + this.dx[i];
            int nextY = y + this.dy[i];

            if (nextX >= 0 &&
                    nextX < this.rowSize &&
                    nextY >= 0 &&
                    nextY < this.columnSize &&
                    this.maps[nextX][nextY] == 1 &&
                    !this.visited[nextX][nextY]
            ) {
                recursiveDfs(nextX, nextY, cnt);
            }
        }

        this.visited[x][y] = false; // 백트래킹
    }
}

위와 같이 코드를 수정하였지만 아쉽게도 효율성 테스트에서는 여전히 모두 실패하였다.

BFS로 풀면 맨 처음에 도출된 값이 최소 횟수인 것이 보장되므로 BFS로 풀어야 하는 것 같다.

✨ 성공 코드

import java.util.LinkedList;
import java.util.Queue;

class Solution {
    // 상, 하, 좌, 우
    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};

    public int solution(int[][] maps) {
        int rowSize = maps.length;
        int columnSize = maps[0].length;

        Block[][] blocks = new Block[rowSize][columnSize];

        for (int i = 0; i < rowSize; i++) {
            for (int j = 0; j < columnSize; j++) {
                blocks[i][j] = new Block(i, j, maps[i][j]);
            }
        }

        Queue<Block> queue = new LinkedList();
        blocks[0][0].cnt = 1;
        blocks[0][0].visited = true;
        queue.offer(blocks[0][0]);

        while (!queue.isEmpty()) {
            Block cur = queue.poll();

            if (cur.x == blocks.length - 1 && cur.y == blocks[0].length - 1) {
                return blocks[cur.x][cur.y].cnt;
            }

            for (int i = 0; i < 4; i++) {
                int newX = cur.x + this.dx[i];
                int newY = cur.y + this.dy[i];

                if (newX >= 0 &&
                        newX < blocks.length &&
                        newY >= 0 &&
                        newY < blocks[0].length &&
                        blocks[newX][newY].data == 1 &&
                        !blocks[newX][newY].visited
                ) {
                    blocks[newX][newY].cnt = cur.cnt + 1;
                    queue.offer(blocks[newX][newY]);
                    blocks[newX][newY].visited = true;
                }
            }
        }

        return -1;
    }

    static class Block {
        int x;
        int y;
        int data;
        boolean visited;
        int cnt;

        public Block(int x, int y, int data) {
            this.x = x;
            this.y = y;
            this.data = data;
            this.visited = false;
        }
    }
}

'스터디 > 99클럽 코테 스터디 TIL' 카테고리의 다른 글

99클럽 코테 스터디 37일차 부등호  (0) 2024.08.28
99클럽 코테 스터디 36일차 전력망을 둘로 나누기  (0) 2024.08.27
99클럽 코테 스터디 34일차 타겟 넘버  (0) 2024.08.25
99클럽 코테 스터디 33일차 리코쳇 로봇  (0) 2024.08.24
99클럽 코테 스터디 32일차 무인도 여행  (0) 2024.08.22
'스터디/99클럽 코테 스터디 TIL' 카테고리의 다른 글
  • 99클럽 코테 스터디 37일차 부등호
  • 99클럽 코테 스터디 36일차 전력망을 둘로 나누기
  • 99클럽 코테 스터디 34일차 타겟 넘버
  • 99클럽 코테 스터디 33일차 리코쳇 로봇
Been
Been
  • Been
    Been
    Been
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • 언어 (0)
        • Kotlin (0)
      • 안드로이드 (17)
      • iOS (3)
      • Git (1)
      • 스터디 (39)
        • 알고리즘 문제 풀이 (1)
        • 99클럽 코테 스터디 TIL (38)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Android
    Coroutines
    TIL
    리싸이클러뷰
    항해99
    NSR
    RecyclerView
    Git
    안드로이드
    nsl
    자바
    언더라인 제거
    풀이실패
    쓰기권한
    debugRuntimeClasspath
    객체변환
    EditText
    아이폰
    코딩테스트준비
    maxWidth
    IOS
    99클럽
    FragmentStateAdapter
    개발자취업
    AndroidID
    밑줄제거
    깃
    WRITE EXTERNAL
    Androiod
    java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Been
99클럽 코테 스터디 35일차 게임 맵 최단거리
상단으로

티스토리툴바