https://leetcode.com/problems/max-area-of-island/
Max Area of Island - LeetCode
Can you solve this real interview question? Max Area of Island - You are given an m x n binary matrix grid. An island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are su
leetcode.com
# 문제
# 예시
Example 1:
Input: grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
Output: 6
Explanation: The answer is not 11, because the island must be connected 4-directionally.
Example 2:
Input: grid = [[0,0,0,0,0,0,0,0]]
Output: 0
# Constraints:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 50
- grid[i][j] is either 0 or 1.
# 해석
처음에 최적화의 집중하다 보니 틀린 풀이에 접근하였다.
이 풀이를 통해서 다음 DFS문제를 풀 때, 더 빠르고 좋은 해답을 적기 위해 글을 적는다.
(1) 2중 for문으로 직사각형을 훑으며 내려가며 검사하는 방법을 생각했다.
이때, 처음 생각한 방법은
이전에 포스팅했던
https://codewizard.tistory.com/29
[stack] 백준 24463번, 미로
https://www.acmicpc.net/problem/24463 24463번: 미로 첫 번째 줄에는 미로의 크기 $N, M$이 주어진다. $(3 \le N, M \le 2,001$, $N, M$은 홀수$)$ 두 번째 줄부터는 미로의 정보가 주어진다. 두 번째 줄부터 $N$줄에 거
codewizard.tistory.com
영상처리 알고리즘을 이용한 풀이를 생각했다.
case를 4개로 검사하는 거다.
나는 이방식으로 풀 수 있었지만, 정확한 시간복잡도를 미리 생각해보지 않았고
이 방식으로 보통 풀라고 낸 출제자의 의도가 아님을 알았다.
미리 시간복잡도적으로 생각을 해보았다면 썼을 수도 있다고 생각한다.
왜냐하면 "코딩테스트를 준비"를 위해서 문제를 풀고 있었기 때문에 시간 안에 빠른 정답도출이 문제였다.
그래서 DFS로 접근하였다.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
len_col = len(grid[0]) # 열
len_row = len(grid) # 행
# 결과 보기
# for i in range(len(grid)):
# print(grid[i])
max_area = 0
for i in range(len_row): # 행만큼 반복
for j in range(len_col): # 열만큼 반복
if grid[i][j] == 1: # 새로운 섬이라면
area = self.dfs(grid, i, j)
max_area = max(area, max_area)
print("max:", max_area)
return max_area
def dfs(self, grid, y, x):
# 상하좌우 검색, 상좌는 이미 갔다옴
area = 1
grid[y][x] = 0 # 방문섬 표시
# 하
# if y+1 < len(grid): # 더 작을때만
# if grid[y+1][x] == 1: # 같은 섬이라면
if y + 1 < len(grid) and grid[y + 1][x] == 1:
area += self.dfs(grid, y+1, x)
# 우
if x + 1 < len(grid[0]) and grid[y][x + 1] == 1:
# if x+1 < len(grid[0]): # 더 작을때만
# if grid[y][x+1] == 1:
area += self.dfs(grid, y, x+1)
return area
처음 접근한 코드다.
이 방법을 이용하여 예제 1번을 입력하면
정답이 5가 나온다.
사진에 주황색이 가장커서 6이나오는데
나는 for문이 우, 하 방향으로 나아가는 것에 집중하다 보니
보라색에서 1,2번으로 가게 짰더니 위로 가지 않아서 1개가 무시되어
답이 5가 나왔다.
sol: 따라서 이 코드를 통해서 얻은 것은 인접 DFS를 검사할 때, 인접한 것을 모두 검사하되
idx값이 밖으로 나가는지 안 나가는지만 파악한다.
# 솔루션 코드
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
len_col = len(grid[0]) # 열
len_row = len(grid) # 행
# 결과 보기
# for i in range(len(grid)):
# print(grid[i])
max_area = 0
for i in range(len_row): # 행만큼 반복
for j in range(len_col): # 열만큼 반복
if grid[i][j] == 1: # 새로운 섬이라면
area = self.dfs(grid, i, j)
max_area = max(area, max_area)
print("max:", max_area)
return max_area
def dfs(self, grid, y, x):
# 하나라도 만족하면 갈 수 없음.
# 아래 상하좌우에서 그냥 무조건 반복하고
# 반복했을 때 조건에 어긋나면 섬을 나간거임
if x<0 or y<0 or x+1>len(grid[0]) or y+1>len(grid) or grid[y][x] != 1:
return 0
# 유효하다면 그때 방문가능섬 표시
area = 1
grid[y][x] = 0 # 방문섬 표시
# 상하좌우
area += self.dfs(grid, y-1, x) # 상
area += self.dfs(grid, y+1, x) # 하
area += self.dfs(grid, y, x-1) # 좌
area += self.dfs(grid, y, x+1) # 우
return area
이것이 좋은 코드인 것 같다.
if문에서
1) idx 값이 나가는지 안 나가는지 4개의 확인
2) 마지막 or == 1이 아닌지 맞는지 검사한다.
정도의 과정을 통해서 dfs를 부를 수 있다.
# 얻은 점
- 방문 지점을 그냥 0으로 처리한다. (최적화) => 나는 인접행렬에 저장하고 다시 확인하는 작업을 거치려 했다.
- 그러지 않고 바로바로 max를 통해서 제일 큰 값을 비교하면 된다.
'Programming > Algorithm(Python)' 카테고리의 다른 글
[그리디, 투포인터] 프로그래머스 구명보트(파이썬) (0) | 2023.11.15 |
---|---|
[코테준비] Python, 꼭 기억해야하는 함수 (0) | 2023.11.15 |
[DFS] leetcode 841번 Keys and Rooms, class이해 (2) | 2023.10.18 |
[구현] SWEA 10570 제곱 팰린드롬 수 (2) | 2023.10.16 |
[구현] SWEA 1284번 수도 요금 경쟁 (2) | 2023.10.12 |