코딩테스트 - 프로그래머스/JAVA

[프로그래머스 / 코딩테스트 입문 / 자바(JAVA)] 안전지대

읁; 2024. 3. 5. 11:36

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/120866

 

프로그래머스

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

programmers.co.kr

 

나의 풀이

로직

  1. 위험지역을 표시하기 위해, 주어진 board와 같은 크기의 2차원 배열 danger를 만든다.
  2. board 배열의 원소들을 하나하나 돌며, 해당 원소가 1일 경우, danger의 같은 자리와 그 주변의 값을 1로 표기한다.
  • board[i][j]==1 일 경우, 값을 1로 해야 할 danger의 원소는 아래와 같다.
    • danger[i][j]
    • danger[i][j-1]
    • danger[i][j+1]
    • danger[i-1][j]
    • danger[i-1][j-1]
    • danger[i-1][j+1]
    • danger[i+1][j]
    • danger[i+1][j-1]
    • danger[i+1][j+1]
  1. 단, 1이 위치한 곳이 (0,0) 또는 (board.length-1, board.length-1) 일 수도 있음을 유의해 코드를 짜도록 한다.
  2. 위험지역을 다 표기한 후, 이번에는 danger의 원소를 하나씩 돌며 0인 경우 int answer++을 하도록 한다.
  3. answer를 return 한다.

 

내 코드

class Solution {
    public int solution(int[][] board) {
        int lth = board.length;
        int[][] danger = new int[lth][lth];

        // 위험지역 표시하기
        for(int i=0; i<lth; i++) {
            for(int j=0; j<lth; j++) {
                if(board[i][j]==1) {
                // 1이 위치한 곳이 (0,0) 또는 (board.length-1, board.length-1) 일 수도 있음을 유의
                    int iminus = Math.max(i-1, 0);
                    int iplus = Math.min(i+1,board.length-1);
                    int jminus = Math.max(j-1, 0);
                    int jplus = Math.min(j+1, board.length-1);

                    danger[i][j] = 1;
                    danger[i][jminus] = 1;
                    danger[i][jplus] = 1;
                    danger[iplus][jminus] = 1;
                    danger[iplus][j] = 1;
                    danger[iplus][jplus] = 1;
                    danger[iminus][jminus] = 1;
                    danger[iminus][j] = 1;
                    danger[iminus][jplus] = 1;
                }
            }
        }

        // 위험지역 세기
        int answer = 0;

         for(int i=0; i<lth; i++) {
            for(int j=0; j<lth; j++) {
                if(danger[i][j]==0) answer++;      
            }
         }

        return answer;
    }
}

 

채점 결과

정확성  테스트
테스트 1 〉    통과 (0.05ms, 71.9MB)
테스트 2 〉    통과 (0.04ms, 65MB)
테스트 3 〉    통과 (0.05ms, 77.1MB)
테스트 4 〉    통과 (0.05ms, 71.5MB)
테스트 5 〉    통과 (0.05ms, 78.4MB)
테스트 6 〉    통과 (0.05ms, 66.5MB)
테스트 7 〉    통과 (0.06ms, 74.3MB)
테스트 8 〉    통과 (0.01ms, 73.1MB)
테스트 9 〉    통과 (0.05ms, 71.8MB)
테스트 10 〉    통과 (0.04ms, 67.3MB)
테스트 11 〉    통과 (0.04ms, 75.2MB)
테스트 12 〉    통과 (0.04ms, 74.8MB)
테스트 13 〉    통과 (0.04ms, 77.6MB)
테스트 14 〉    통과 (0.06ms, 66.1MB)
채점 결과
정확성: 100.0
합계: 100.0 / 100.0

 

 

좋은 풀이

코드

expelia81@gmail.com , ZettaKim , 최호경 님의 코드

class Solution {
    public int solution(int[][] board) {
        int answer = 0;
        int length = board.length;   //길이
        int[][] temp = new int[length+2][length+2];
        // 길이를 2 늘린 액자용 배열 생성 -> 이러면 단순한 조건식으로 안전영역 구할 수 있음

        // 액자에 board 이식.
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                temp[i][j]=board[i-1][j-1];
            }
        }

        //위험지대 찾기
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                if(temp[i][j]==1){
                    for(int a = i-1; a<=i+1; a++){
                        for(int b =j-1; b<=j+1; b++){
                            if(temp[a][b]!=1) temp[a][b]=2;
                        }
                    }
                }
            }
        }

        // 안전지대 카운트
        for(int i=1; i<length+1; i++){
            for(int j=1; j<length+1;j++){
                if(temp[i][j]==0) answer++;
                System.out.print(temp[i][j]);
            }
            System.out.println("");
        }


        return answer;
    }
}

 

배운 점

 

board 배열에서 1이 위치한 곳이 (0,0) 또는 (board.length-1, board.length-1) 일 수도 있음을 유의하는 방법으로,
길이를 2 늘린 액자용 배열을 생성해 코드를 단순화한 것이 인상깊다.