Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
Given a 1-indexed m x n integer matrix mat, you can select any cell in the matrix as your starting cell.
From the starting cell, you can move to any other cell in the same row or column, but only if the value of the destination cell is strictly greater than the value of the current cell. You can repeat this process as many times as possible, moving from cell to cell until you can no longer make any moves.
Your task is to find the maximum number of cells that you can visit in the matrix by starting from some cell.
Return an integer denoting the maximum number of cells that can be visited.
Example 1:
Input: mat = [[3,1],[3,4]] Output: 2 Explanation: The image shows how we can visit 2 cells starting from row 1, column 2. It can be shown that we cannot visit more than 2 cells no matter where we start from, so the answer is 2.
Example 2:
Input: mat = [[1,1],[1,1]] Output: 1 Explanation: Since the cells must be strictly increasing, we can only visit one cell in this example.
Example 3:
Input: mat = [[3,1,6],[-9,5,7]] Output: 4 Explanation: The image above shows how we can visit 4 cells starting from row 2, column 1. It can be shown that we cannot visit more than 4 cells no matter where we start from, so the answer is 4.
Constraints:
m == mat.length n == mat[i].length 1 <= m, n <= 1051 <= m * n <= 105-105 <= mat[i][j] <= 105Problem summary: Given a 1-indexed m x n integer matrix mat, you can select any cell in the matrix as your starting cell. From the starting cell, you can move to any other cell in the same row or column, but only if the value of the destination cell is strictly greater than the value of the current cell. You can repeat this process as many times as possible, moving from cell to cell until you can no longer make any moves. Your task is to find the maximum number of cells that you can visit in the matrix by starting from some cell. Return an integer denoting the maximum number of cells that can be visited.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Binary Search · Dynamic Programming · Segment Tree
[[3,1],[3,4]]
[[1,1],[1,1]]
[[3,1,6],[-9,5,7]]
number-of-increasing-paths-in-a-grid)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
class Solution {
public int maxIncreasingCells(int[][] mat) {
int m = mat.length, n = mat[0].length;
TreeMap<Integer, List<int[]>> g = new TreeMap<>();
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
g.computeIfAbsent(mat[i][j], k -> new ArrayList<>()).add(new int[] {i, j});
}
}
int[] rowMax = new int[m];
int[] colMax = new int[n];
int ans = 0;
for (var e : g.entrySet()) {
var pos = e.getValue();
int[] mx = new int[pos.size()];
int k = 0;
for (var p : pos) {
int i = p[0], j = p[1];
mx[k] = Math.max(rowMax[i], colMax[j]) + 1;
ans = Math.max(ans, mx[k++]);
}
for (k = 0; k < mx.length; ++k) {
int i = pos.get(k)[0], j = pos.get(k)[1];
rowMax[i] = Math.max(rowMax[i], mx[k]);
colMax[j] = Math.max(colMax[j], mx[k]);
}
}
return ans;
}
}
// Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
func maxIncreasingCells(mat [][]int) (ans int) {
m, n := len(mat), len(mat[0])
g := map[int][][2]int{}
for i, row := range mat {
for j, v := range row {
g[v] = append(g[v], [2]int{i, j})
}
}
nums := make([]int, 0, len(g))
for k := range g {
nums = append(nums, k)
}
sort.Ints(nums)
rowMax := make([]int, m)
colMax := make([]int, n)
for _, k := range nums {
pos := g[k]
mx := make([]int, len(pos))
for i, p := range pos {
mx[i] = max(rowMax[p[0]], colMax[p[1]]) + 1
ans = max(ans, mx[i])
}
for i, p := range pos {
rowMax[p[0]] = max(rowMax[p[0]], mx[i])
colMax[p[1]] = max(colMax[p[1]], mx[i])
}
}
return
}
# Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
class Solution:
def maxIncreasingCells(self, mat: List[List[int]]) -> int:
m, n = len(mat), len(mat[0])
g = defaultdict(list)
for i in range(m):
for j in range(n):
g[mat[i][j]].append((i, j))
rowMax = [0] * m
colMax = [0] * n
ans = 0
for _, pos in sorted(g.items()):
mx = []
for i, j in pos:
mx.append(1 + max(rowMax[i], colMax[j]))
ans = max(ans, mx[-1])
for k, (i, j) in enumerate(pos):
rowMax[i] = max(rowMax[i], mx[k])
colMax[j] = max(colMax[j], mx[k])
return ans
// Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
// class Solution {
// public int maxIncreasingCells(int[][] mat) {
// int m = mat.length, n = mat[0].length;
// TreeMap<Integer, List<int[]>> g = new TreeMap<>();
// for (int i = 0; i < m; ++i) {
// for (int j = 0; j < n; ++j) {
// g.computeIfAbsent(mat[i][j], k -> new ArrayList<>()).add(new int[] {i, j});
// }
// }
// int[] rowMax = new int[m];
// int[] colMax = new int[n];
// int ans = 0;
// for (var e : g.entrySet()) {
// var pos = e.getValue();
// int[] mx = new int[pos.size()];
// int k = 0;
// for (var p : pos) {
// int i = p[0], j = p[1];
// mx[k] = Math.max(rowMax[i], colMax[j]) + 1;
// ans = Math.max(ans, mx[k++]);
// }
// for (k = 0; k < mx.length; ++k) {
// int i = pos.get(k)[0], j = pos.get(k)[1];
// rowMax[i] = Math.max(rowMax[i], mx[k]);
// colMax[j] = Math.max(colMax[j], mx[k]);
// }
// }
// return ans;
// }
// }
// Accepted solution for LeetCode #2713: Maximum Strictly Increasing Cells in a Matrix
function maxIncreasingCells(mat: number[][]): number {
const m = mat.length;
const n = mat[0].length;
const g: { [key: number]: [number, number][] } = {};
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (!g[mat[i][j]]) {
g[mat[i][j]] = [];
}
g[mat[i][j]].push([i, j]);
}
}
const rowMax = Array(m).fill(0);
const colMax = Array(n).fill(0);
let ans = 0;
const sortedKeys = Object.keys(g)
.map(Number)
.sort((a, b) => a - b);
for (const key of sortedKeys) {
const pos = g[key];
const mx: number[] = [];
for (const [i, j] of pos) {
mx.push(1 + Math.max(rowMax[i], colMax[j]));
ans = Math.max(ans, mx[mx.length - 1]);
}
for (let k = 0; k < pos.length; k++) {
const [i, j] = pos[k];
rowMax[i] = Math.max(rowMax[i], mx[k]);
colMax[j] = Math.max(colMax[j], mx[k]);
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.
Wrong move: An incomplete state merges distinct subproblems and caches incorrect answers.
Usually fails on: Correctness breaks on cases that differ only in hidden state.
Fix: Define state so each unique subproblem maps to one DP cell.