title: Check if Matrix Is X-Matrix slug: check-if-matrix-is-x-matrix difficulty: easy leetcode_id: 2319 leetcode_url: https://leetcode.com/problems/check-if-matrix-is-x-matrix/ categories: - arrays - math patterns: - matrix-traversal function_signature: "def check_x_matrix(grid: list[list[int]]) -> bool:" test_cases: visible: - input: { grid: [[2, 0, 0, 1], [0, 3, 1, 0], [0, 5, 2, 0], [4, 0, 0, 2]] } expected: true - input: { grid: [[5, 7, 0], [0, 3, 1], [0, 5, 0]] } expected: false hidden: - input: { grid: [[1, 0, 1], [0, 1, 0], [1, 0, 1]] } expected: true - input: { grid: [[1, 0, 0], [0, 1, 0], [0, 0, 1]] } expected: false - input: { grid: [[0, 0, 1], [0, 1, 0], [1, 0, 0]] } expected: false - input: { grid: [[5, 0, 5], [0, 5, 0], [5, 0, 5]] } expected: true description: | A square matrix is said to be an **X-Matrix** if **both** of the following conditions hold: 1. All the elements in the diagonals of the matrix are **non-zero**. 2. All other elements are `0`. Given a 2D integer array `grid` of size `n x n` representing a square matrix, return `true` *if* `grid` *is an X-Matrix*. Otherwise, return `false`. constraints: | - `n == grid.length == grid[i].length` - `3 <= n <= 100` - `0 <= grid[i][j] <= 10^5` examples: - input: "grid = [[2,0,0,1],[0,3,1,0],[0,5,2,0],[4,0,0,2]]" output: "true" explanation: "The diagonal elements (positions where i == j or i + j == n - 1) are all non-zero: 2, 1, 3, 1, 5, 2, 4, 2. All other elements are 0. Thus, grid is an X-Matrix." - input: "grid = [[5,7,0],[0,3,1],[0,5,0]]" output: "false" explanation: "The element at position (0,1) is 7, which should be 0 since it's not on a diagonal. Also, position (1,2) is 1 instead of 0. Thus, grid is not an X-Matrix." explanation: intuition: | Imagine drawing a large "X" across a square grid. The "X" touches the four corners and crosses in the center. These positions form the **two diagonals** of the matrix: - **Primary diagonal**: runs from top-left to bottom-right (where row index equals column index: `i == j`) - **Anti-diagonal**: runs from top-right to bottom-left (where row plus column equals `n - 1`: `i + j == n - 1`) Think of it like this: you're a quality inspector checking each cell of the grid. At every position, you need to answer one question: "Am I on a diagonal?" If yes, the value must be non-zero. If no, the value must be zero. The key insight is that determining whether a position `(i, j)` lies on a diagonal is a simple mathematical check — no need to pre-compute or store the diagonal positions. This allows us to verify the X-Matrix property in a single pass through the grid. approach: | We solve this using a **Single Pass Matrix Traversal**: **Step 1: Iterate through every cell** - Use nested loops to visit each position `(i, j)` in the grid - For each cell, determine if it lies on a diagonal   **Step 2: Check diagonal membership** - A cell `(i, j)` is on the primary diagonal if `i == j` - A cell `(i, j)` is on the anti-diagonal if `i + j == n - 1` - Combined: a cell is on *some* diagonal if `i == j` or `i + j == n - 1`   **Step 3: Validate the cell value** - If the cell is on a diagonal: check that `grid[i][j] != 0` - If the cell is NOT on a diagonal: check that `grid[i][j] == 0` - If any check fails, immediately return `false`   **Step 4: Return the result** - If we complete the traversal without finding any violations, return `true`   This approach works because we exhaustively check every cell exactly once, ensuring both conditions of the X-Matrix definition are satisfied. common_pitfalls: - title: Forgetting the Anti-Diagonal description: | A common mistake is only checking the primary diagonal (`i == j`) and forgetting that the anti-diagonal (`i + j == n - 1`) is also part of the "X" shape. For example, in a 3x3 grid, position `(0, 2)` and `(2, 0)` are on the anti-diagonal but not the primary diagonal. Missing this check would incorrectly require these cells to be zero. wrong_approach: "Only checking i == j for diagonals" correct_approach: "Check both i == j and i + j == n - 1" - title: Off-By-One in Anti-Diagonal Check description: | The anti-diagonal condition is `i + j == n - 1`, not `i + j == n`. Remember that indices are 0-based, so for an `n x n` matrix, the anti-diagonal connects positions like `(0, n-1)`, `(1, n-2)`, ..., `(n-1, 0)`. If you use `i + j == n`, you'll be checking positions that don't exist or missing the actual anti-diagonal. wrong_approach: "Using i + j == n for anti-diagonal" correct_approach: "Use i + j == n - 1 for anti-diagonal" - title: Checking Only One Condition description: | Both conditions must be checked for every cell: - Diagonal cells must be **non-zero** - Non-diagonal cells must be **zero** Some solutions only verify that diagonals are non-zero, forgetting to check that everything else is zero, or vice versa. wrong_approach: "Only checking diagonals are non-zero, ignoring other cells" correct_approach: "Verify both conditions: diagonals non-zero AND others zero" key_takeaways: - "**Diagonal identification**: In an `n x n` matrix, primary diagonal positions satisfy `i == j`, anti-diagonal positions satisfy `i + j == n - 1`" - "**Early exit optimisation**: Return `false` immediately upon finding any violation rather than checking all cells first" - "**Matrix traversal pattern**: Nested loops with `O(n^2)` complexity are acceptable when you must inspect every cell" - "**Simple validation problems**: When verifying properties, translate the definition directly into conditional checks" time_complexity: "O(n^2). We visit each of the n × n cells exactly once to verify its value." space_complexity: "O(1). We only use a constant amount of extra space for loop variables and comparisons." solutions: - approach_name: Single Pass Validation is_optimal: true code: | def check_x_matrix(grid: list[list[int]]) -> bool: n = len(grid) for i in range(n): for j in range(n): # Check if this position is on either diagonal on_diagonal = (i == j) or (i + j == n - 1) if on_diagonal: # Diagonal elements must be non-zero if grid[i][j] == 0: return False else: # Non-diagonal elements must be zero if grid[i][j] != 0: return False # All checks passed return True explanation: | **Time Complexity:** O(n^2) — We iterate through all n × n cells once. **Space Complexity:** O(1) — Only a few variables used regardless of input size. We check each cell exactly once. For diagonal positions (where `i == j` or `i + j == n - 1`), we verify the value is non-zero. For all other positions, we verify the value is zero. Any violation causes an immediate return of `false`. - approach_name: Condensed Boolean Check is_optimal: true code: | def check_x_matrix(grid: list[list[int]]) -> bool: n = len(grid) for i in range(n): for j in range(n): on_diagonal = (i == j) or (i + j == n - 1) # XOR-like logic: diagonal and non-zero, or not diagonal and zero if on_diagonal != (grid[i][j] != 0): return False return True explanation: | **Time Complexity:** O(n^2) — Same traversal as the first approach. **Space Complexity:** O(1) — Constant extra space. This condensed version uses a clever boolean comparison. The condition `on_diagonal != (grid[i][j] != 0)` returns `True` (invalid) when: - The cell is on a diagonal but has value 0, OR - The cell is not on a diagonal but has a non-zero value Both cases represent violations of the X-Matrix property.