문제
https://programmers.co.kr/learn/courses/30/lessons/12905?language=python3
풀이
우선 처음에 잘못 접근했던 코드부터 기록해볼까 한다.
def solution(board):
cube = [0] * len(board[0])
for row in board :
cube = [c+r for c,r in zip(cube, row)]
max_val = max(cube)
while max_val > 0 :
max_len = 0
start = cube.index(max_val)
for i in range(start, len(cube)):
if cube[i] >= max_val : max_len += 1
if max_len == max_val : return max_val**2
if cube[i] < max_val : max_len = 0
max_val -= 1
return 0
행 단위로 훑으면서 각 열별로 덧셈을 진행한다.
0 1 1 1
1 1 1 1
1 1 1 1
0 0 1 0
---------------
2 3 4 3
덧셈이 완료된 상태에서, 가장 큰 값을 비교 값으로 잡아
한 행씩 비교하면서 비교 값보다 크거나 같은 값을 카운트 한다.
그러다 비교 값과 같은 길이가 나오면 그 비교값의 제곱을 정답으로 반환한다.
2 3 4 3
---------------
4 -> 1
3 -> 3
return 3^2
접근은 그럴듯 했으나, 결과는 처참했다.
테스트 1 〉 통과 (0.01ms, 10.2MB)
테스트 2 〉 통과 (0.02ms, 10.1MB)
테스트 3 〉 통과 (0.02ms, 10.2MB)
테스트 4 〉 통과 (0.02ms, 10.2MB)
테스트 5 〉 통과 (0.02ms, 10.2MB)
테스트 6 〉 실패 (0.02ms, 10.3MB)
테스트 7 〉 실패 (런타임 에러)
테스트 8 〉 통과 (0.02ms, 10.3MB)
테스트 9 〉 실패 (런타임 에러)
테스트 10 〉 실패 (런타임 에러)
테스트 11 〉 실패 (런타임 에러)
테스트 12 〉 실패 (런타임 에러)
테스트 13 〉 실패 (0.02ms, 10.2MB)
테스트 14 〉 실패 (런타임 에러)
테스트 15 〉 실패 (런타임 에러)
테스트 16 〉 실패 (0.03ms, 10.2MB)
테스트 17 〉 실패 (런타임 에러)
테스트 18 〉 실패 (런타임 에러)
테스트 19 〉 실패 (런타임 에러)
심지어 이리저리 뒤틀어봐도 시간초과까지 뜨는 상황이었다.
도저히 방법이 떠오르지 않아서 결국 검색의 힘을 빌렸다.
아래는 CodeDrive블로그를 참고한 결과다.
def solution(board):
zero_check = 0
for row in board :
zero_check += sum(row)
if zero_check == 0 : return 0
max_val = 1
for i in range(1, len(board)) :
for j in range(1, len(board[0])) :
if board[i][j] == 0 : continue
board[i][j] = min(board[i][j-1], board[i-1][j], board[i-1][j-1]) + 1
if board[i][j] > max_val :
max_val = board[i][j]
return max_val ** 2
- 첫 번째 반복문에서 모든 행을 탐색하면서 1이 없는지 확인한다.
- 두 번째 반복문부터 (1,1) 블럭을 기준으로 탐색을 시작하는데, 좌, 좌상, 상단을 확인하기 떄문이다.
- 만약 (i, j)가 0이라면 사각형이 아니므로 탐색할 필요가 없다.
- 만약 (i, j)가 1이라면, 좌, 좌상, 상단을 확인해서 최소값+1을 대입시킨다.
코드 설명은 이정도로 된거같고, 어떤 현상이 일어나나 직접 확인해보자.
#1
0 1 1 1
1 *1 1 1 좌상에서 최소값 0 발견, +1 대입
1 1 1 1
0 0 1 0
#2
0 1 1 1
1 1 *1 1 최소값 1 발견, +1 대입
1 1 1 1
0 0 1 0
#3
0 1 1 1
1 1 2 *1 최소값 1 발견, +1 대입
1 1 1 1
0 0 1 0
#4
0 1 1 1
1 1 2 2 최소값 1 발견, +1 대입
1 *1 1 1
0 0 1 0
#5
0 1 1 1
1 1 2 2 최소값 1 발견, +1 대입
1 2 *1 1
0 0 1 0
#6
0 1 1 1
1 1 2 2 최소값 2 발견, +1 대입
1 2 2 *1
0 0 1 0
#7
0 1 1 1
1 1 2 2 최소값 2 발견, +1 대입
1 2 2 3
0 0 *1 0
Dynamic Programming을 통한 해결 방법이었는데,
분명 학부과정에서 접한 경험이 있는 풀이 방식이다.
2차원 배열 문제를 마주했을 때 떠올릴 수 있도록 기억파편을 꼭 남겨두자.
댓글남기기