Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find island count by adding blocks into grid one by one in Python
Suppose we have an infinite grid of water. We can add blocks of land to that grid one by one. We have a list of coordinates called land_requests where each coordinate is in the form [r, c] where r is for row and c is for column. We need to find a list where each element represents the number of islands that exist after adding each block of land from land_requests.
For example, if the input is land_requests = [[1, 1], [2, 4], [1, 2], [1, 4], [1, 3]], then the output will be [1, 2, 2, 2, 1].
Algorithm Overview
This problem uses the Union-Find (Disjoint Set Union) data structure to efficiently track connected components (islands). The approach is ?
For each new land block, initially consider it as a separate island
Check all 4 adjacent directions for existing land blocks
If adjacent land exists, merge the islands using Union-Find
Track the total number of connected components
Implementation
class Solution:
def __init__(self):
self.directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]
def find(self, u):
"""Find root with path compression"""
if u == self.parent[u]:
return u
self.parent[u] = self.find(self.parent[u])
return self.parent[u]
def union(self, u, v):
"""Union two components by rank"""
pu = self.find(u)
pv = self.find(v)
if pu == pv:
return
# Merge components - reduce island count
self.island_count -= 1
# Union by size for better performance
if self.size[pu] >= self.size[pv]:
self.parent[pv] = pu
self.size[pu] += self.size[pv]
else:
self.parent[pu] = pv
self.size[pv] += self.size[pu]
def count_islands(self, land_requests):
"""Count islands after adding each land block"""
self.idx = 0
self.coordinate_map = {}
self.parent = []
self.size = []
self.island_count = 0
result = []
for row, col in land_requests:
# Add new land block
self.coordinate_map[(row, col)] = self.idx
self.parent.append(self.idx)
self.size.append(1)
self.idx += 1
self.island_count += 1
# Check all 4 adjacent directions
for dr, dc in self.directions:
new_row = row + dr
new_col = col + dc
# If adjacent cell has land, union them
if (new_row, new_col) in self.coordinate_map:
current_id = self.coordinate_map[(row, col)]
adjacent_id = self.coordinate_map[(new_row, new_col)]
self.union(current_id, adjacent_id)
result.append(self.island_count)
return result
# Test the solution
solution = Solution()
land_requests = [[1, 1], [2, 4], [1, 2], [1, 4], [1, 3]]
result = solution.count_islands(land_requests)
print("Land requests:", land_requests)
print("Island count after each addition:", result)
Land requests: [[1, 1], [2, 4], [1, 2], [1, 4], [1, 3]] Island count after each addition: [1, 2, 2, 2, 1]
How It Works
Let's trace through the example step by step ?
Add [1,1]: First land block creates 1 island ? count = 1
Add [2,4]: No adjacent land, creates new island ? count = 2
Add [1,2]: Adjacent to [1,1], they merge ? count = 2 (still 2 islands)
Add [1,4]: No connection to existing islands ? count = 3, but then connects to [2,4] ? count = 2
Add [1,3]: Connects [1,2] group with [1,4] group, merging all into 1 island ? count = 1
Time and Space Complexity
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Find with path compression | O(?(n)) ? O(1) | O(1) |
| Union by rank/size | O(?(n)) ? O(1) | O(1) |
| Overall algorithm | O(k × ?(k)) | O(k) |
Where k is the number of land requests and ? is the inverse Ackermann function.
Conclusion
This solution efficiently tracks island formation using Union-Find data structure. Each land addition checks 4 directions and merges connected components, maintaining an accurate island count in near-constant time per operation.
