Problem of The Day: Count Servers that Communicate
Problem Statement
Intuition
The problem involves identifying servers that can communicate with at least one other server in the same row or column. My first thought was to simulate the communication network by checking every server and identifying all servers it can directly or indirectly connect to.
Approach
-
Initialization:
- Create a queue to process each server’s position
(row, column)
in the grid. - Use a
seen
set to store all unique servers that are part of a communication network.
- Create a queue to process each server’s position
-
Iterate Through the Grid:
- Traverse the grid, and for every cell containing
1
(indicating a server), add its position to the queue.
- Traverse the grid, and for every cell containing
-
Simulate Communication:
- For each server
(r, c)
dequeued, traverse the entire rowr
and columnc
to find other servers that can communicate with it. Store all these servers’ positions in avisited
set. - If the size of
visited
is greater than 1, it means the current server can communicate with others, so update the globalseen
set with thevisited
servers.
- For each server
-
Result:
- The final size of the
seen
set gives the count of servers that can communicate with at least one other server.
- The final size of the
Complexity
-
Time complexity:
- Traversing the grid takes \(O(R \times C)\), where \(R\) is the number of rows and \(C\) is the number of columns.
- For each server in the queue, we traverse its entire row and column, which is \(O(R + C)\) for each server. In the worst case, this could add up to \(O(R \times C \times (R + C))\).
- Therefore, the overall time complexity is \(O(R \times C \times (R + C))\).
-
Space complexity:
- The
queue
,seen
, andvisited
sets can collectively use up to \(O(R \times C)\) space in the worst case. - Hence, the space complexity is \(O(R \times C)\).
- The
Code
class Solution:
def countServers(self, grid: List[List[int]]) -> int:
res = 0
ROWS = len(grid)
COLS = len(grid[0])
queue = deque()
seen = set()
for row in range(ROWS):
for col in range(COLS):
if grid[row][col] == 1:
queue.append([row, col])
while queue:
r, c = queue.popleft()
visited = set()
for row in range(ROWS):
if grid[row][c] == 1:
visited.add((row, c))
for col in range(COLS):
if grid[r][col] == 1:
visited.add((r, col))
if len(visited) > 1:
seen.update(visited)
return len(seen)
Editorial
Approach 1: Brute-Force
class Solution:
def countServers(self, grid: List[List[int]]) -> int:
num_rows = len(grid)
num_cols = len(grid[0]) if num_rows > 0 else 0
communicable_servers_count = 0
# Traverse through the grid
for row in range(num_rows):
for col in range(num_cols):
if grid[row][col] == 1:
can_communicate = False
# Check for communication in the same row
for other_col in range(num_cols):
if other_col != col and grid[row][other_col] == 1:
can_communicate = True
break
# If a server was found in the same row, increment
# communicable_servers_count
if can_communicate:
communicable_servers_count += 1
else:
# Check for communication in the same column
for other_row in range(num_rows):
if other_row != row and grid[other_row][col] == 1:
can_communicate = True
break
# If a server was found in the same column, increment
# communicable_servers_count
if can_communicate:
communicable_servers_count += 1
return communicable_servers_count
Approach 2: Track Using Two Arrays
class Solution:
def countServers(self, grid: List[List[int]]) -> int:
if not grid:
return 0
row_counts = [0] * len(grid[0])
col_counts = [0] * len(grid)
# Count servers in each row and each column
for row in range(len(grid)):
for col in range(len(grid[0])):
if grid[row][col]:
row_counts[col] += 1
col_counts[row] += 1
communicable_servers_count = 0
# Count servers that can communicate (in the same row or column)
for row in range(len(grid)):
for col in range(len(grid[0])):
if grid[row][col]:
if row_counts[col] > 1 or col_counts[row] > 1:
communicable_servers_count += 1
return communicable_servers_count
Approach 3: Server Grouping
class Solution:
def countServers(self, grid: List[List[int]]) -> int:
communicable_servers_count = 0
row_counts = [0] * len(grid[0])
last_server_in_col = [-1] * len(grid)
# First pass to count servers in each row and column
for row in range(len(grid)):
server_count_in_row = 0
for col in range(len(grid[0])):
if grid[row][col]:
server_count_in_row += 1
row_counts[col] += 1
last_server_in_col[row] = col
# If there is more than one server in the row, increase the count
if server_count_in_row != 1:
communicable_servers_count += server_count_in_row
last_server_in_col[row] = -1
# Second pass to check if servers can communicate
for row in range(len(grid)):
if (
last_server_in_col[row] != -1
and row_counts[last_server_in_col[row]] > 1
):
communicable_servers_count += 1
return communicable_servers_count