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.
Move from brute-force thinking to an efficient approach using array strategy.
There is a dungeon with n x m rooms arranged as a grid.
You are given a 2D array moveTime of size n x m, where moveTime[i][j] represents the minimum time in seconds after which the room opens and can be moved to. You start from the room (0, 0) at time t = 0 and can move to an adjacent room. Moving between adjacent rooms takes exactly one second.
Return the minimum time to reach the room (n - 1, m - 1).
Two rooms are adjacent if they share a common wall, either horizontally or vertically.
Example 1:
Input: moveTime = [[0,4],[4,4]]
Output: 6
Explanation:
The minimum time required is 6 seconds.
t == 4, move from room (0, 0) to room (1, 0) in one second.t == 5, move from room (1, 0) to room (1, 1) in one second.Example 2:
Input: moveTime = [[0,0,0],[0,0,0]]
Output: 3
Explanation:
The minimum time required is 3 seconds.
t == 0, move from room (0, 0) to room (1, 0) in one second.t == 1, move from room (1, 0) to room (1, 1) in one second.t == 2, move from room (1, 1) to room (1, 2) in one second.Example 3:
Input: moveTime = [[0,1],[1,2]]
Output: 3
Constraints:
2 <= n == moveTime.length <= 502 <= m == moveTime[i].length <= 500 <= moveTime[i][j] <= 109Problem summary: There is a dungeon with n x m rooms arranged as a grid. You are given a 2D array moveTime of size n x m, where moveTime[i][j] represents the minimum time in seconds after which the room opens and can be moved to. You start from the room (0, 0) at time t = 0 and can move to an adjacent room. Moving between adjacent rooms takes exactly one second. Return the minimum time to reach the room (n - 1, m - 1). Two rooms are adjacent if they share a common wall, either horizontally or vertically.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[[0,4],[4,4]]
[[0,0,0],[0,0,0]]
[[0,1],[1,2]]
minimum-cost-to-reach-destination-in-time)minimum-time-to-visit-a-cell-in-a-grid)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3341: Find Minimum Time to Reach Last Room I
class Solution {
public int minTimeToReach(int[][] moveTime) {
int n = moveTime.length;
int m = moveTime[0].length;
int[][] dist = new int[n][m];
for (var row : dist) {
Arrays.fill(row, Integer.MAX_VALUE);
}
dist[0][0] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
pq.offer(new int[] {0, 0, 0});
int[] dirs = {-1, 0, 1, 0, -1};
while (true) {
int[] p = pq.poll();
int d = p[0], i = p[1], j = p[2];
if (i == n - 1 && j == m - 1) {
return d;
}
if (d > dist[i][j]) {
continue;
}
for (int k = 0; k < 4; k++) {
int x = i + dirs[k];
int y = j + dirs[k + 1];
if (x >= 0 && x < n && y >= 0 && y < m) {
int t = Math.max(moveTime[x][y], dist[i][j]) + 1;
if (dist[x][y] > t) {
dist[x][y] = t;
pq.offer(new int[] {t, x, y});
}
}
}
}
}
}
// Accepted solution for LeetCode #3341: Find Minimum Time to Reach Last Room I
func minTimeToReach(moveTime [][]int) int {
n, m := len(moveTime), len(moveTime[0])
dist := make([][]int, n)
for i := range dist {
dist[i] = make([]int, m)
for j := range dist[i] {
dist[i][j] = math.MaxInt32
}
}
dist[0][0] = 0
pq := &hp{}
heap.Init(pq)
heap.Push(pq, tuple{0, 0, 0})
dirs := []int{-1, 0, 1, 0, -1}
for {
p := heap.Pop(pq).(tuple)
d, i, j := p.dis, p.x, p.y
if i == n-1 && j == m-1 {
return d
}
if d > dist[i][j] {
continue
}
for k := 0; k < 4; k++ {
x, y := i+dirs[k], j+dirs[k+1]
if x >= 0 && x < n && y >= 0 && y < m {
t := max(moveTime[x][y], dist[i][j]) + 1
if dist[x][y] > t {
dist[x][y] = t
heap.Push(pq, tuple{t, x, y})
}
}
}
}
}
type tuple struct{ dis, x, y int }
type hp []tuple
func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].dis < h[j].dis }
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any) { *h = append(*h, v.(tuple)) }
func (h *hp) Pop() (v any) { a := *h; *h, v = a[:len(a)-1], a[len(a)-1]; return }
# Accepted solution for LeetCode #3341: Find Minimum Time to Reach Last Room I
class Solution:
def minTimeToReach(self, moveTime: List[List[int]]) -> int:
n, m = len(moveTime), len(moveTime[0])
dist = [[inf] * m for _ in range(n)]
dist[0][0] = 0
pq = [(0, 0, 0)]
dirs = (-1, 0, 1, 0, -1)
while 1:
d, i, j = heappop(pq)
if i == n - 1 and j == m - 1:
return d
if d > dist[i][j]:
continue
for a, b in pairwise(dirs):
x, y = i + a, j + b
if 0 <= x < n and 0 <= y < m:
t = max(moveTime[x][y], dist[i][j]) + 1
if dist[x][y] > t:
dist[x][y] = t
heappush(pq, (t, x, y))
// Accepted solution for LeetCode #3341: Find Minimum Time to Reach Last Room I
/**
* [3341] Find Minimum Time to Reach Last Room I
*/
pub struct Solution {}
// submission codes start here
use std::cmp::Ordering;
use std::collections::BinaryHeap;
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord)]
struct State {
x: usize,
y: usize,
distance: i32,
}
impl State {
fn new(x: usize, y: usize, distance: i32) -> Self {
Self { x, y, distance }
}
}
impl PartialOrd for State {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
// BinaryHeap是大顶堆
Some(other.distance.cmp(&self.distance))
}
}
impl Solution {
pub fn min_time_to_reach(move_time: Vec<Vec<i32>>) -> i32 {
let n = move_time.len();
let m = move_time[0].len();
let mut distances = vec![vec![i32::MAX; m]; n];
let mut visited = vec![vec![false; m]; n];
let mut heap = BinaryHeap::new();
distances[0][0] = 0;
heap.push(State::new(0, 0, 0));
while let Some(head) = heap.pop() {
if visited[head.x][head.y] {
continue;
}
visited[head.x][head.y] = true;
for &(dx, dy) in DIRECTIONS.iter() {
let next = head
.x
.checked_add_signed(dx)
.and_then(|x| head.y.checked_add_signed(dy).and_then(|y| Some((x, y))))
.filter(|(x, y)| x < &n && y < &m);
if let Some((x, y)) = next {
let distance = distances[head.x][head.y].max(move_time[x][y]) + 1;
if distances[x][y] > distance {
distances[x][y] = distance;
heap.push(State::new(x, y, distance));
}
}
}
}
distances[n - 1][m - 1]
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_3341() {
assert_eq!(6, Solution::min_time_to_reach(vec![vec![0, 4], vec![4, 4]]));
assert_eq!(
3,
Solution::min_time_to_reach(vec![vec![0, 0, 0], vec![0, 0, 0]])
);
assert_eq!(3, Solution::min_time_to_reach(vec![vec![0, 1], vec![1, 2]]));
}
}
// Accepted solution for LeetCode #3341: Find Minimum Time to Reach Last Room I
function minTimeToReach(moveTime: number[][]): number {
const n = moveTime.length;
const m = moveTime[0].length;
const dist = Array.from({ length: n }, () => Array(m).fill(Infinity));
dist[0][0] = 0;
type Node = [number, number, number];
const pq = new PriorityQueue<Node>((a, b) => a[0] - b[0]);
pq.enqueue([0, 0, 0]);
const dirs = [-1, 0, 1, 0, -1];
while (!pq.isEmpty()) {
const [d, i, j] = pq.dequeue();
if (d > dist[i][j]) continue;
if (i === n - 1 && j === m - 1) return d;
for (let k = 0; k < 4; ++k) {
const x = i + dirs[k];
const y = j + dirs[k + 1];
if (x >= 0 && x < n && y >= 0 && y < m) {
const t = Math.max(moveTime[x][y], d) + 1;
if (t < dist[x][y]) {
dist[x][y] = t;
pq.enqueue([t, x, y]);
}
}
}
}
return -1;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
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.