Swim in Rising Water
WHAT IT SAYS
Water rises one unit per tick; a cell is enterable once the level reaches its height; find the earliest time you can travel from the top-left to the bottom-right.
WHAT IT'S REALLY ASKING
"At any water level t, the passable world is fixed: exactly the cells of height ≤ t. Raising t only ADDS cells — the passable world grows monotonically — so the question is 'at what threshold do start and end first become connected?' Sort the cells by height, admit them one by one, union each into its admitted neighbours, and the answer is the height of the cell whose admission first links the two corners."
Simulate the ticks
O(maxHeight · mn) — a full connectivity check per water levelFor t = 0, 1, 2, ...: run a BFS over cells of height ≤ t; stop at the first t where the destination is reachable.
WHERE THE WORK IS WASTED — Consecutive levels differ by a handful of newly admitted cells, yet each tick's BFS rebuilds the entire reachable region from nothing — the connectivity computed at level t is thrown away and recomputed, plus epsilon, at t+1. Monotonicity is the squandered asset twice over: it means each check's result implies nothing needs re-verifying (admitted cells never retract), so the work should ACCUMULATE across levels; and it means feasibility is a sorted yes/no line, so even keeping the recomputation, binary search over t would slash the level count logarithmically. Linear scan with amnesia is the worst point in a design space with two independent escapes.
Admit cells in height order; the answer is the link.
Monotone growth is the whole structure: the passable set at threshold t contains the passable set at every smaller threshold, so connectivity events happen ONCE and never un-happen. That licenses processing admissions as a single accumulating stream instead of per-level snapshots. Sort all cells by height; sweep the thresholds in that order; when a cell is admitted, it can only connect through neighbours ALREADY admitted (lower or equal height) — union it with each such neighbour. Connectivity is thereby maintained incrementally — union-find's exact contract, insertion-only — and after each admission one O(α) query asks: do the two corners share a root yet? The FIRST admission after which they do gives the answer: its height is the minimal viable water level, because at every smaller threshold the sweep had already admitted everything passable and the corners were still separate — the sweep IS the proof of minimality, an exhaustive check of all lower thresholds performed cumulatively rather than repeatedly. Recognise the lineage: this is Kruskal's algorithm with the destination changed — Kruskal admits edges in weight order until a spanning tree forms; here cells are admitted in height order until one specific pair connects. Both are instances of threshold connectivity: sort by the parameter, insert in order, stop at the connectivity event you care about. The bottleneck value of the minimax path (the largest height you're forced through) is exactly the threshold at the event — which reveals the kinship with Path With Minimum Effort: SAME minimax objective, and indeed modified Dijkstra (relax with max(pathMax, cellHeight)) solves this problem too, in the same O(mn log mn). The two files split the two unlocks deliberately: Dijkstra generalises the combiner; Kruskal-style sweep converts monotone-threshold questions into incremental union — and the sweep is the one that survives when the question is about connectivity events rather than per-node optima (e.g., 'when do ALL cells connect'). Binary search on t with a BFS feasibility check is the third valid route — the monotone yes/no line again — costing O(mn log maxHeight): worth naming because it needs no union-find and no Dijkstra proof, only the monotonicity observation.
Sort cells, union on admission, stop when the corners link
O(mn log(mn)) for the sort (O(mn) if heights are a permutation) plus O(mn · α) unionsCells sorted ascending by height; DSU over r·n + c; an admitted[] marker. Sweep: admit the next cell, union with each in-bounds admitted neighbour, then if find(start) == find(end), return the current cell's height. (Heights being a permutation of 0..mn−1 in the classic statement lets a bucket array replace the sort.)
Sort by Threshold, Union to the Event
YOU'LL SEE IT AGAIN WHEN
- The passable/usable set grows monotonically with a scalar parameter — admissions never retract, so connectivity work can accumulate.
- The answer is the parameter value at a CONNECTIVITY EVENT — two nodes linking, everything linking, k components remaining.
- Kruskal's shape fits: sort by the parameter, insert in order, query after each insertion — union-find's insertion-only contract, exactly.