728x90
 

프로그래머스

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

programmers.co.kr

[문제 설명]

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으로만 이루어져 있습니다.

입출력 예

 

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중 반복문으로 문제를 풀 수 있는 방법을 찾아야했다.

그 방법은 아래와 같다.

 

왼쪽에서 오른쪽, 위에서 아래로 확인하면서 값을 저장하는 방법이다. 값을 저장하면서 나아가는 로직은 주로 메모이제이션이라고 할 수 있다.

 

1. 현재 위치의 값이 1이면 아래의 과정을 거친다.

 

2. 왼쪽[i,j-1], 왼쪽 대각선 위[i-1,j-1], 위[i-1,j] 위치의 값을 확인하고 제일 낮은 값에 1을 더한값을 현재 위치에 저장한다.

 => 2번에서 하는 것은 왼쪽, 왼쪽대각선 위, 위의 값을 확인하여 현재위치에서 만들수 있는 가장 큰 정사각형을 찾아내는 과정이다.

 

3. 모든 위치를 확인할때까지 1~2번을 반복하고, 가장 큰 값을 answer 변수에 저장한다.

 

위의 로직대로 코드를 작성하면 문제를 맞출수있다.

내가 짠 로직에서 두번째 줄과 열부터 탐색을 하게 되는데, 이때 조심해야 할 것은 answer의 초기값 설정 부분이다.

무턱대고 0으로 넣어두면 첫번째칸 board[0][0]의 값이 1일때를 캐치하지 못한다.

따라서 answer의 값을 board[0][0]의 값으로 설정해주는것이 맞다.

 

[코드]

[GitHub]

 

GitHub - EGyeom/ProblemSolving

Contribute to EGyeom/ProblemSolving development by creating an account on GitHub.

github.com

#include <algorithm>
#include <vector>
using namespace std;

int solution(vector<vector<int>> board)
{
    int answer = board[0][0];
    int boardYSize = board.size();
    int boardXSize = board[0].size();
    for(int i = 1 ; i < boardYSize; i++)
    {
        for(int j = 1; j < boardXSize; j++)
        {
            if(board[i][j] == 1)
            {
                board[i][j] = min({board[i-1][j-1], board[i-1][j], board[i][j-1]}) + 1;
                answer = max(board[i][j], answer);
            }
        }
    }

    return answer*answer;
}
복사했습니다!