문제 설명
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 |
1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 |
0 | 0 | 1 | 0 |
가 되며 넓이는 9가 되므로 9를 반환해 주면 됩니다.
- 제한사항
- 표(board)는 2차원 배열로 주어집니다.
- 표(board)의 행(row)의 크기 : 1,000 이하의 자연수
- 표(board)의 열(column)의 크기 : 1,000 이하의 자연수
- 표(board)의 값은 1또는 0으로만 이루어져 있습니다.
- 입출력 예 #1
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 |
- 입출력 예 #2
0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 |
로 가장 큰 정사각형의 넓이는 4가 되므로 4를 return합니다.
이 문제를 풀기 앞서..
수 많은 검색 끝에 이 문제를 풀기 위해선 Dynamic Programming(동적 계획법)을 사용해야 한단 것을 알았습니다.
DP에 대해 간략히 설명하자면
Dynamic Programming(동적 계획법)
기본적인 아이디어로 하나의 큰 문제를 여러 개의 작은 문제로 나누어서 그 결과를 저장하여 다시 큰 문제를 해결할 때 사용하는 것.
DP를 사용하기 위해선 다음 2가지 조건을 만족해야한다.
1) Overlapping Subproblems(겹치는 부분 문제)
2) Optimal Substructure(최적 부분 구조)
더 자세한 내용을 설명하기엔 길어지기에 자세한 내용은 아래 포스팅한 게시글을 읽어보시면 이해되실 겁니다.
2022.09.19 - [코딩테스트] - [알고리즘] 동적 프로그래밍 (DP) 란? feat.동적 계획법
문제를 이해하기 위해
이 문제를 이해하는데 상당히 많은 시간이 걸렸어서 그림으로 쉽게 이해를 돕고자 합니다.
아래의 코드를 보시면서 보신다면 훨 씬 이해가 빠르실 겁니다.
- 만약 행 또는 열이 1이면 정사각형의 넓이는 1
- 루프를 돌며 만약 자신의 위치(현재 인덱스)의 값이 1이상일 경우 왼쪽상단(↖︎), 위쪽(↑), 왼쪽(←)의 최솟값을 구한 후 자신의 위치에 최솟값 + 1을 할당
- i 가 0이 아닌 1부터 시작하는 이유는 좌측값, 상단값, 대각선값을 확인하여 현재값을 변경하기 때문입니다.
- 1행 1열 부터 시작하여 한 열에서 하나의 행을 다 돌고 다음 열로 넘어갑니다.
- 순환이 끝나면 배열의 가장 큰 값이 현재 배열의 가장 큰 정사각형의 값이 됩니다.
- 사각형의 넓이는 한 변의 길이 * 한 변의 길이로 정사각형은 변의 길이가 같기 때문에 한변의 길이 2제곱을 해줍니다.
1열 순환 예시
현재위치의 값을 제외한 좌측값, 상단값, 대각선값을 비교하여 가장 작은 값 + 1로 현재값을 변경합니다.
- [1, 1] 1행 1열
가장 작은 값이 대각선의 값 0이 므로 현재 값은 0+1 인 1이 됩니다.
- [2, 1] 2행 1열
가장 작은 값이 좌측값, 상단값, 대각선값 모두 1 이므로 현재 값은 1+1 인 2가 됩니다.
- [3, 1] 3행 1열
가장 작은 값이 상단값, 대각선값인 1 이므로 현재 값은 1+1 인 2가 됩니다.
2열 순환 예시
- [1, 2] 1행 2열
가장 작은 값이 좌측값, 상단값, 대각선값 모두 1 이므로 현재 값은 1+1 인 2가 됩니다.
- [2, 2] 2행 2열
가장 작은 값이 대각선값 1 이므로 현재 값은 1+1 인 2가 됩니다.
- [3, 2] 3행 2열
가장 작은 값이 좌측값, 상단값, 대각선값 모두 2 이므로 현재 값은 2+1 인 3이 됩니다.
3열 순환 예시
- [1, 3] 1행 3열
board [i] [j] > 0 으로 0보다 커야하지만 크지 않기 때문에 2행으로 넘어갑니다.
- [2, 3] 2행 3열
가장 작은 값이 좌측값 0 이므로 현재 값은 0+1 인 1이 됩니다.
- [3, 3] 3행 3열
board [i] [j] > 0 으로 0보다 커야하지만 크지 않기 때문에 넘어가며 i < board.length , i < board[0].length 의 길이인 4 전 까지이기 때문에
for 구문은 종료됩니다.
전체 순환 그림
한 눈에 보기 편하도록 위 순환 열들을 합친 그림도 첨부합니다.
그림이 많이 조잡하네요 ..

solution.js
마지막으로 코드 첨부합니다.
위 풀이 방법들을 보시면서 코드를 보시면 이해하기 편하실겁니다.
혹시나 이해 안되는 부분있으면 댓글 남겨주세요 (●'◡'●)
function solution(board) {
let answer = 0;
const row = board.length;
const column = board[0].length;
if (row <= 1 || column <= 1) return 1;
for (let i = 1; i < row; i++) { // 1행부터 시작
for (let j = 1; j < column; j++) { // 1열부터 시작
if (board[i][j] > 0) {
const up = board[i - 1][j];
const left = board[i][j - 1];
const cross = board[i - 1][j - 1];
const minNum = Math.min(up, left, cross); // 3개의 값 중 가장 작은 값
board[i][j] = minNum + 1;
console.log(board[i][j]);
answer = Math.max(answer, board[i][j]);
}
}
}
return answer **2;
}
'◼ 코딩테스트 > 구현 (Implementation)' 카테고리의 다른 글
(javascript) 알고리즘 - 스티커 모으기 (완벽설명, 이해) (4) | 2022.09.20 |
---|---|
(javascript) 알고리즘 문제 - 땅따먹기 ( 완벽이해, 설명 ) (1) | 2022.09.19 |
(javascript) 알고리즘 문제 - 나머지 한 점 (1) | 2022.09.16 |
(javascript) 알고리즘 문제 - 순열 검사 (1) | 2022.09.16 |
(javascript) 알고리즘 문제 - 자릿수 더하기 (1) | 2022.09.16 |