Notes & software courses · Free to learn
Aph's Blog
On this page

2352. Equal Row and Column Pairs

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

Ledger row shapes with Counter, then build each column and query the ledger.

Given a 0-indexed n x n integer matrix grid, return the number of pairs (ri, cj) such that row ri and column cj are equal.

A row and column pair is considered equal if they contain the same elements in the same order (i.e., an equal array).

Example 1
Input:
grid = [[3,2,1],[1,7,6],[2,7,7]]
Output:
1
Explanation:
There is 1 equal row and column pair: (Row 2, Column 1): [2,7,7].
Example 2
Input:
grid = [[3,1,2,2],[1,4,4,5],[2,4,2,2],[2,4,2,2]]
Output:
3
Explanation:
There are 3 equal row and column pairs: (Row 0, Column 0): [3,1,2,2]; (Row 2, Column 2): [2,4,2,2]; (Row 3, Column 2): [2,4,2,2].
Constraints (ข้อจำกัด)
  • n == grid.length == grid[i].length
  • 1 <= n <= 200
  • 1 <= grid[i][j] <= 10^5

Order matters: [2,7,7] matches [2,7,7] only, not [7,2,7]. Duplicate-looking rows each form their own pairs.

Understand the problem — what are we counting?

You're given a square grid of numbers. Count how many rows look exactly like some column.

Take this 3×3 example:

Unpack rows / cols from the grid
(row 0)    3    2    1
(row 1)    1    7    6
(row 2)    2    7    7

Row: (3, 2, 1), (1, 7, 6), (2, 7, 7)
Col: (3, 1, 2), (2, 7, 7), (1, 6, 7)

Bottom row (2, 7, 7) = middle column (2, 7, 7) → 1 pair

Approach — keep a ledger

Comparing every row against every column is slow and messy. Better: two phases.

  1. Phase 1 "ledger": scan every row and record "this shape appeared how many times?"
  2. Phase 2 "check": for each column, ask the ledger "does this shape exist?" If yes, add that count to the score
Common pitfalls

Add row_count[col], not just +1 — duplicate rows each pair with this column. Counter returns 0 for missing keys, so you won’t get a KeyError.

Walkthrough — ledger and columns

After phase 1 the ledger is {(3, 2, 1): 1, (1, 7, 6): 1, (2, 7, 7): 1}. Then for j in range(n) build each column:

jcol builtask the ledgerpairs so far
0(3, 1, 2)missing → 00
1(2, 7, 7)hit → 11
2(1, 6, 7)missing → 01

Loop ends with pairs = 1 — exact match.

Try it yourself first

Ledger and walkthrough table are above — write it yourself, then open the fold below when stuck or ready to compare.

Solution code · folded so you can try firstพับไว้ด้านใน — คลิกเมื่อพร้อมดู

Core: ledger row shapes in a Counter, then build each column and query — add the count, not +1.

Python — runnablepython
from collections import Counter

def equal_pairs(grid):
    # --- Phase 1: ledger the rows ---
    n = len(grid)
    row_count = Counter(tuple(row) for row in grid)
    # {(3, 2, 1): 1, (1, 7, 6): 1, (2, 7, 7): 1}

    pairs = 0

    # --- Phase 2: build each column and query the ledger ---
    for j in range(n):
        # lock column j, let row i walk top → bottom
        col = tuple(grid[i][j] for i in range(n))
        pairs += row_count[col]

    return pairs

print(equal_pairs([[3, 2, 1], [1, 7, 6], [2, 7, 7]]))  # 1
print(equal_pairs([[3, 1, 2, 2], [1, 4, 4, 5],
                   [2, 4, 2, 2], [2, 4, 2, 2]]))        # 3
Output
1
3

What to notice

  • tuple(row) — lists can’t be dict keys; forget the conversion and it crashes
  • col = tuple(grid[i][j] for i in range(n)) locks column j and walks row i top → bottom
  • pairs += row_count[col] adds every matching row count, not just +1
  • Counter returns 0 for missing keys — no need for if key in … before adding
Column-build linepython
col = tuple(grid[i][j] for i in range(n))  # j = 0 → (3, 1, 2)
Time · Space

Time O(n²) one pass over rows + one pass building columns · Space O(n²) storing all row tuples in the Counter

💡 Pattern takeaway

When matching identical items across two groups, don’t compare every pair. Count one group into a hash map, then query the other one by one. Remember: list/row as a key → convert to tuple first. Trap: add row_count[col], not +1.