1267. Count Servers that Communicate - Explanation

Problem Link

Description

You are given a map of a server center, represented as a m * n integer matrix grid, where 1 means that on that cell there is a server and 0 means that it is no server. Two servers are said to communicate if they are on the same row or on the same column.

Return the number of servers that communicate with any other server.

Example 1:

Input: grid = [
    [1,1,0,0],
    [0,0,1,0],
    [0,0,1,0],
    [0,0,0,1]
]

Output: 4

Explanation: Except for the server at the position (3,3), all other servers have other servers to communicate.

Example 2:

Input: grid = [
    [1,0],
    [1,1]
]

Output: 3

Explanation: All three servers can communicate with at least one other server.

Constraints:

  • 1 <= grid.length, grid[i].length <= 250
  • grid[i][j] == 0 or 1


Topics

Company Tags

Please upgrade to NeetCode Pro to view company tags.



Prerequisites

Before attempting this problem, you should be comfortable with:

  • 2D Matrix Traversal - Iterating through rows and columns of a grid using nested loops
  • Counting with Arrays - Using auxiliary arrays to track counts per row and column
  • In-place Marking - Modifying grid values to mark visited or processed cells (for space-optimized solution)

1. Brute Force

Intuition

A server can communicate if there is at least one other server in the same row or column. For each server, we can directly check its entire row and column to see if any other server exists. If we find at least one, this server counts toward our result.

Algorithm

  1. Iterate through each cell in the grid.
  2. For each cell containing a server (value 1):
    • Check all other cells in the same row for another server.
    • If not found in the row, check all other cells in the same column.
    • If another server is found in either the row or column, increment the result.
  3. Return the total count of servers that can communicate.
class Solution:
    def countServers(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        res = 0

        for r in range(m):
            for c in range(n):
                if grid[r][c] == 0:
                    continue

                found = False
                for col in range(n):
                    if col != c and grid[r][col] == 1:
                        found = True
                        break

                if not found:
                    for row in range(m):
                        if row != r and grid[row][c] == 1:
                            found = True
                            break

                if found:
                    res += 1

        return res

Time & Space Complexity

  • Time complexity: O(mn2)O(m * n ^ 2)
  • Space complexity: O(1)O(1)

Where mm is the number of rows and nn is the number of columns of the given matrix gridgrid.


2. Iteration

Intuition

Instead of checking each server's row and column individually, we can precompute the count of servers in each row and column. A server can communicate if there is more than one server in its row or more than one server in its column. This allows us to determine each server's status in constant time after the preprocessing step.

Algorithm

  1. Create two arrays: row_cnt to store server counts per row and col_cnt for columns.
  2. First pass: Count the number of servers in each row and column.
  3. Second pass: For each server, check if its row count or column count is greater than 1.
    • If yes, this server can communicate with at least one other server.
  4. Return the total count of communicating servers.
class Solution:
    def countServers(self, grid: List[List[int]]) -> int:
        ROWS, COLS = len(grid), len(grid[0])
        row_cnt = [0] * ROWS
        col_cnt = [0] * COLS

        for r in range(ROWS):
            for c in range(COLS):
                if grid[r][c] == 1:
                    row_cnt[r] += 1
                    col_cnt[c] += 1

        res = 0
        for r in range(ROWS):
            for c in range(COLS):
                if grid[r][c] and max(row_cnt[r], col_cnt[c]) > 1:
                    res += 1

        return res

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity: O(m+n)O(m + n)

Where mm is the number of rows and nn is the number of columns of the given matrix gridgrid.


3. Iteration (Space Optimized)

Intuition

We can avoid using extra arrays by processing rows and columns separately and using the grid itself to mark processed servers. First, we process all rows with multiple servers and mark those servers. Then, we process columns and only count unmarked servers in columns with multiple servers. The marking prevents double counting servers that belong to both a communicating row and column.

Algorithm

  1. Process rows first:
    • For each row with more than one server, add all servers in that row to the result.
    • Mark these servers by setting their value to -1.
  2. Process columns:
    • For each column, count total servers (using absolute values) and unmarked servers.
    • If the column has two or more servers, add the count of unmarked servers to the result.
    • Restore marked servers by setting -1 back to 1.
  3. Return the total count.
class Solution:
    def countServers(self, grid: List[List[int]]) -> int:
        res = 0
        ROWS, COLS = len(grid), len(grid[0])

        # Rows
        for r in range(ROWS):
            row_sum = sum(grid[r])
            if row_sum <= 1:
                continue
            res += row_sum
            for c in range(COLS):
                if grid[r][c]:
                    grid[r][c] = -1  # Mark

        # Cols
        for c in range(COLS):
            col_sum = unmarked = 0
            for r in range(ROWS):
                col_sum += abs(grid[r][c])
                if grid[r][c] > 0:
                    unmarked += 1
                elif grid[r][c] < 0:
                    grid[r][c] = 1 # Unmark
            if col_sum >= 2:
                res += unmarked

        return res

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity: O(1)O(1)

Where mm is the number of rows and nn is the number of columns of the given matrix gridgrid.


Common Pitfalls

Counting Total Servers Instead of Communicating Servers

A server only counts if it can communicate with at least one other server. Counting all servers (all cells with value 1) ignores the communication requirement.

Using OR Instead of Checking Both Row and Column Counts

A server communicates if its row has 2+ servers OR its column has 2+ servers. Using AND would incorrectly require both conditions.

# Wrong: requires both row AND column to have multiple servers
if row_cnt[r] > 1 and col_cnt[c] > 1:
# Correct: either condition is sufficient
if row_cnt[r] > 1 or col_cnt[c] > 1:

Double Counting Servers

When processing rows and columns separately (in the space-optimized solution), servers that are in both a communicating row and a communicating column can be counted twice. Mark processed servers to avoid this.