일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Apache Spark
- heapq
- Apache Hadoop
- DP
- Python
- 분산처리
- 리트코드
- 그래프
- 아파치 하둡
- 프로그래머스
- docker
- 아파치 카프카
- apache kafka
- String
- 우선순위큐
- 오블완
- 도커
- 알고리즘
- 티스토리챌린지
- 문자열
- BFS
- programmers
- leetcode
- 분산
- 이진탐색
- 아파치 스파크
- 하둡
- 파이썬
- 카프카
- 코딩테스트
- Today
- Total
래원
[LeetCode] 827. Making A Large Island (Python) 본문
난이도: Hard
문제 설명
You are given an n x n
binary matrix grid
. You are allowed to change at most one 0
to be 1
.
Return the size of the largest island in grid
after applying this operation.
An island is a 4-directionally connected group of 1
s.
문제 예제
Example 1:
Input: grid = [[1,0],[0,1]]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.
Example 2:
Input: grid = [[1,1],[1,0]]
Output: 4
Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.
Example 3:
Input: grid = [[1,1],[1,1]]
Output: 4
Explanation: Can't change any 0 to 1, only one island with area = 4.
제한 사항
n == grid.length
n == grid[i].length
1 <= n <= 500
grid[i][j]
is either0
or1
.
Solution(솔루션)
def check_only_one_num(n, grid):
only_one, only_zero = False, False
for i in range(n):
for j in range(n):
if grid[i][j] == 0:
only_zero = True
else:
only_one = True
if only_zero and not only_one:
return 1
elif not only_zero and only_one:
return n*n
else:
return False
def bfs(grid, n, i, j, visited, moves, root):
visited[i][j] = True
q = deque([(i,j)])
area = 0
path = []
while q:
x, y = q.popleft()
area+=1
path.append((x, y))
for move in moves:
nx = x + move[0]
ny = y + move[1]
if 0<=nx<n and 0<=ny<n and not visited[nx][ny] and grid[nx][ny] == 1:
visited[nx][ny] = True
q.append((nx, ny))
for x, y in path:
grid[x][y] = area
root[x][y] = (n*i + j)
def get_area(grid, n, i, j, root, moves):
check_root = set()
area = 1
for move in moves:
nx = i + move[0]
ny = j + move[1]
if 0<=nx<n and 0<=ny<n and grid[nx][ny] != 0:
r = root[nx][ny]
if r not in check_root:
check_root.add(r)
area += grid[nx][ny]
return area
class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
n = len(grid)
check = check_only_one_num(n, grid)
if check != False:
return check
moves = [[0,1], [0,-1], [1,0], [-1,0]]
visited = [[False]*n for _ in range(n)]
root = [[0]*n for _ in range(n)]
for i in range(n):
for j in range(n):
if grid[i][j] == 1 and not visited[i][j]:
bfs(grid, n, i, j, visited, moves, root)
answer = 0
for i in range(n):
for j in range(n):
if grid[i][j] == 0:
area = get_area(grid, n, i, j, root, moves)
answer = max(answer, area)
return answer
재미있는 문제였던 것 같다.
먼저 grid가 모두 0으로 되어있다면 1을 return하게 하고, 모두 1로 되어있다면 n*n을 return하도록 했다.
처음에는 다음과 같이 모든 0에 대해 이 0을 1로 바꾼다고 했을 때를 가정하고 bfs를 돌려 제일 큰 영역을 찾았다.
하지만, 이 방법은 TLE가 발생했다. 확실히 0이 많다고하면 오래 걸릴 것 같긴 했다.
그래서 다른 방법을 생각하다가 아래 그림과 같이 먼저 1로 이루어진 영역을 찾아 그 영역의 크기를 저장해놓고, 모든 0에 대해서 (1 + 상하좌우의 영역)의 크기하면 되지 않을까 였다.
하지만 이 역시 문제가 있었다. 모든 0에 대해서 (1+상하좌우 영역의 크기)를 진행하는데 만약 상하좌우의 영역들이 이미 연결되있는 영역이면 이를 다 더할 필요가 없다는 것이다.
따라서, 각 영역에 대해 root를 만들었다. 만약 (0, 0)에서 부터 시작해 영역이 만들어 졌다면 그 영역의 인덱스들은 같은 root로 치는 것이다.
이제 다시 모든 0에서 부터 상하좌우의 값을 더해주는데, check_root를 만들어 check_root에 없는 root를 가진 영역이면 더해주고 check_root에 이를 넣어주었다. 만약 check_root에 있는 root를 가진 영역이면 더해주지않고 넘어갔다.
이런식으로 모든 0에서 진행했고 제일 큰 area 값을 answer로 return하여 정답을 맞출 수 있었다.
문제: 827. Making A Large Island
깃허브: github
'알고리즘 > LeetCode' 카테고리의 다른 글
[LeetCode] 3151. Special Array I (Python) (0) | 2025.02.01 |
---|---|
[LeetCode] 785. Is Graph Bipartite? (Python) (0) | 2025.01.30 |
[LeetCode] 2658. Maximum Number of Fish in a Grid (Python) (0) | 2025.01.28 |
[LeetCode] 1462. Course Schedule IV (Python) (0) | 2025.01.27 |
[LeetCode] 2948. Make Lexicographically Smallest Array by Swapping Elements (Python) (0) | 2025.01.25 |