Longest Decreasing Matrix Path with Limited Relaxations
Reported by candidates from Duolingo's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Duolingo reportedly served this one in November 2025, and the trap is hiding in example 2: a coordinate can repeat. If you read it as the classic longest decreasing path and cache by cell alone, you'll fail the k > 0 cases. It's a state-space search on (row, col, relaxations left), and the output is the actual coordinates, not a length. Ties go to the lexicographically smallest sequence. That's a lot to hold in your head with the clock running. StealthCoder sits invisibly on your screen as a safety net if you blank mid-OA, but the pattern below should get you most of the way.
The problem
Given an integer matrix and a nonnegative integer k, return a longest orthogonal path of cell coordinates. A move to an up, down, left, or right neighbor is: free when the next value is strictly smaller than the current value; or a relaxation when the next value is greater than or equal to the current value. The path may use at most k relaxed moves. Because every cycle contains at least one non-decreasing move, the relaxation budget keeps every valid walk finite; a coordinate may therefore be revisited only after spending additional budget. Return the coordinates as [row, column] rows. If several paths have maximum length, return the lexicographically smallest coordinate sequence. Setting k = 0 is the original longest-decreasing-path task, while returning coordinates and accepting positive k preserve both reported follow-ups. Function longestRelaxedDecreasingPath(matrix: int[][], k: int) → int[][] Examples Example 1 matrix = [[9,8,7],[2,3,6],[1,4,5]] k = 0 return = [[0,0],[0,1],[0,2],[1,2],[2,2],[2,1],[1,1],[1,0],[2,0]] The spiral visits values 9, 8, 7, 6, 5, 4, 3, 2, 1. Every move is strictly decreasing, so no relaxation is used. Example 2 matrix = [[1,2]] k = 1 return = [[0,1],[0,0],[0,1],[0,0]] Start at value 2, move down to 1 for free, spend the one relaxation to return to 2, then move down to 1 again. The repeated coordinates have different remaining-budget states. Example 3 matrix = [[4,3],[2,1]] k = 0 return = [[0,0],[0,1],[1,1]] There are multiple decreasing paths of length three. The returned one is lexicographically smallest. Constraints 1 <= matrix.length, matrix[0].length <= 20. All rows have the same length. -10^9 <= matrix[r][c] <= 10^9. 0 <= k <= 5.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is that the state isn't a cell, it's (r, c, budget left). With k at most 5 and a grid at most 20x20, that's about 2400 states, small enough to memoize. Define best(r, c, j) as the longest path starting at that cell with j relaxations left. For each neighbor, a strictly smaller value costs 0 and a value greater than or equal costs 1, which needs j >= 1. Finiteness holds because every cycle burns budget, so the recursion terminates. The pitfall is tie-breaking. Compare by length first, then compare coordinate sequences, and try all four neighbors rather than greedily picking the smallest. Also rebuild the path from stored choices, not just lengths. Starting cells need the same comparison. A plain BFS over paths blows up, so use DFS with memoization over the layered states, or DP ordered by budget.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Longest Decreasing Matrix Path with Limited Relaxations cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Duolingo's OA.
Duolingo reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Longest Decreasing Matrix Path with Limited Relaxations FAQ
What's the trick in the Duolingo longest decreasing matrix path problem?+
Treat the state as (row, col, relaxations left), not just the cell. Example 2 revisits coordinates, so a cell-only cache gives wrong answers when k > 0. Memoize on the triple and the recursion stays small and finite.
How hard is this really?+
Harder than the standard longest increasing path problem. The core DP is familiar, but you also have to return coordinates, handle lexicographic ties, and add the budget dimension. Each piece is easy alone. Combined, it's a medium-hard problem that rewards careful state definition.
How do I handle the lexicographically smallest tie-break?+
Store the best path or a next-pointer per state. When two options have equal length, compare their coordinate sequences and keep the smaller one. Do it across all four neighbors and across all starting cells. Don't assume the first neighbor in scan order wins.
Why can't I just run BFS?+
BFS finds shortest paths, and you want the longest. Enumerating paths explodes exponentially. Memoized DFS over (r, c, budget) gives each state one answer. The hinted BFS idea only works if you layer states by budget, and DFS with a cache is simpler.
How should I prep in 48 hours?+
Solve the classic longest increasing path in a matrix with memoized DFS until it's automatic. Then add a budget dimension and practice reconstructing the path from stored choices. Write the tie-break comparison once so it's ready. Test with k = 0 and the 1x2 example.