본문 바로가기

Algorithm/level2

[ 프로그래머스 - Java & Kotlin ] 가장 큰 정사각형 찾기 ( 자바 & 코틀린 )

728x90

( 경로 / 가장 큰 정사각형 찾기 )

[문제]

문제 설명

1과 0으로 채워진 표(board)가 있습니다. 표 1칸은 1 x 1의 정사각형으로 이루어져 있습니다. 표에서 1로 이루어진 가장 큰 정사각형을 찾아 넓이를 return 하는 solution 함수를 완성해 주세요. (단, 정사각형이란 축에 평행한 정사각형을 말합니다.)

예를 들어

1 2 3 4
0 1 1 1
1 1 1 1
1 1 1 1
0 0 1 0

가 있다면 가장 큰 정사각형은

1 2 3 4
0 1 1 1
0 1 1 1
0 1 1 1
0 0 0 0

가 되며 넓이는 9가 되므로 9를 반환해 주면 됩니다.

제한사항

  • 표(board)는 2차원 배열로 주어집니다.
  • 표(board)의 행(row)의 크기 : 1,000 이하의 자연수
  • 표(board)의 열(column)의 크기 : 1,000 이하의 자연수
  • 표(board)의 값은 1또는 0으로만 이루어져 있습니다.

입출력 예시

board answer
[[0,1,1,1],[1,1,1,1],[1,1,1,1],[0,0,1,0]] 9
[[0,0,1,1],[1,1,1,1]] 4

입출력 예 설명

입출력 예 #1
위의 예시와 같습니다.

 

입출력 예 #2
| 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 |
로 가장 큰 정사각형의 넓이는 4가 되므로 4를 return 합니다.


[풀이]

왼쪽 위에서부터 차례로 가장 큰 정사각형의 변을 구하면 됩니다.

행을 i 열을 j라고 가정했을 경우[i, j] 칸이 0이 아니라면 [i, j-1], [i-1, j] [i-1, j-1] 3개 중에 가장 작은 값에 1을 더해주며 board의 끝까지 연산을 반복합니다.

자세한 설명은 아래 그림을 보시면 이해하는데 도움이 될 것입니다.

가장 큰 정사각형의 변을 계산하는 방법


[주의]

주어진 board의 행이나 열의 크기가 1일 경우 무조건 가장 큰 정사각형은 1이므로 answer에 미리 초기화해줘야 합니다.


[코드]

자바

class Solution{
    public int solution(int [][]board){
        // 가로나 세로가 1일 경우 정사각형은 무조건 1임으로 1로 초기화
        int answer = board.length == 1 || board[0].length == 1 ? 1 : 0;
        // 첫번째 행과 열은 제외하고 반복
        for(int i = 1; i < board.length; i++){
            for(int j = 1; j < board[0].length; j++){
                // 계산할 칸이 0이 아닐 경우 해당 칸에 주변 3개의 칸중에 최소값 + 1을 넣어줌
                // 가장 변이 긴 정사각형은 answer에 저장
                if(board[i][j] != 0){
                    board[i][j] = Math.min(board[i-1][j-1], Math.min(board[i-1][j], board[i][j-1])) + 1;
                    answer = Math.max(board[i][j], answer);
                }
            }
        }
        // 정사각형 계산 후 반환
        return answer * answer;
    }
}

코틀린

fun solution(board:Array<IntArray>):Int{
    // 가로나 세로가 1일 경우 정사각형은 무조건 1임으로 1로 초기화
    var answer = if(board.size == 1 || board[0].size == 1) 1 else 0
    // 첫번째 행과 열은 제외하고 반복
    for(i in 1 until board.size){
        for(j in 1 until board[0].size){
            // 계산할 칸이 0이 아닐 경우 해당 칸에 주변 3개의 칸중에 최소값 + 1을 넣어줌
            // 가장 변이 긴 정사각형은 answer에 저장
            if(board[i][j] != 0){
                board[i][j] = minOf(board[i][j-1], board[i-1][j], board[i-1][j-1]) + 1
                answer = max(board[i][j], answer)
            }
        }
    }
    // 정사각형 계산 후 반환
    return answer * answer
}

문제 링크

 

코딩테스트 연습 - 가장 큰 정사각형 찾기

[[0,1,1,1],[1,1,1,1],[1,1,1,1],[0,0,1,0]] 9

programmers.co.kr

제가 잘못 알고 있거나 잘못된 부분이 있을 경우 알려주시고 추가로 궁금한 점 있으신 분들도 댓글이나 메일 주시면 성실히 답변해 드리겠습니다.🧑🏻‍💻

감사합니다~😄

728x90