We need to find two indices i and j where i < j and nums[i] <= nums[j], and we want to maximize the gap j - i. In other words, we're looking for the widest possible "ramp" where the value at the left end doesn't exceed the value at the right end.
A brute force approach checks every pair (i, j), which is O(n^2). To do better, we need to avoid examining every pair.
The left endpoint i of an optimal ramp is always an index whose value is a "new minimum" as we scan left to right. If nums[i] is not smaller than everything before it, then some earlier index has a value less than or equal to nums[i], and that earlier index pairs with the same j to form a wider ramp. So the candidates for i form a decreasing sequence of values, which a monotonic stack captures directly.
2 <= nums.length <= 5 * 10^4 → With n up to 50,000, an O(n^2) solution performs around 1.25 billion comparisons in the worst case, which is too slow. We need O(n log n) or O(n).0 <= nums[i] <= 5 * 10^4 → Values are non-negative and fit comfortably in a 32-bit integer, so widths and comparisons never overflow.For each left endpoint i, the widest ramp starting there ends at the farthest j with nums[j] >= nums[i]. So instead of testing every j, scan from the right end inward and stop at the first j that works — it is already the farthest one.
The scan still touches every pair in the worst case, so it runs in O(n^2) time, but it exits early on most inputs.
maxWidth = 0.i from 0 to n - 1:j from n - 1 down to i + 1.j where nums[j] >= nums[i], update maxWidth = max(maxWidth, j - i) and stop scanning: no smaller j can give a wider ramp starting at i.maxWidth.Loading animation...
Most of these pairs are irrelevant. If nums[i] is not a "new minimum" going left to right, an earlier index with a smaller value gives a wider ramp with the same right endpoint. The next approach removes the quadratic work by sorting on value and reducing the problem to a gap between original indices.
Sort the elements by value while keeping their original indices. For any two elements in sorted order, the one that appears earlier has a value less than or equal to the later one, so the ramp condition nums[i] <= nums[j] holds for every earlier-later pair. The problem reduces to finding the maximum difference between original indices, where the smaller index comes first in the array.
Iterating through the sorted order, we track the minimum original index seen so far, starting it at n so the first element always claims it. For each element, if its original index is greater than that minimum, the pair forms a valid ramp and the candidate width is the difference; otherwise the element itself becomes the new minimum. The maximum across all elements is the answer. Tie-breaking by index keeps equal values in increasing index order, so equal-valued elements still form valid ramps with each other.
[0, 1, 2, ..., n-1] and sort them by the values in nums. Use index as a tiebreaker (smaller index first).maxWidth = 0 and minIndex = n, a sentinel larger than any real index.idx in the sorted order:idx > minIndex, the pair forms a valid ramp: update maxWidth = max(maxWidth, idx - minIndex).idx is the smallest original index seen so far: set minIndex = idx.maxWidth.Loading animation...
The sorting step dominates the runtime at O(n log n). The next approach identifies the useful left endpoints in one linear pass and matches them with right endpoints in another, dropping the sort and reaching O(n).
This solution runs in O(n) time and rests on two observations.
First, the left endpoint of the optimal ramp belongs to the strictly decreasing prefix of values. If nums[i] is not a new minimum, then some i' < i has nums[i'] <= nums[i], and for any valid ramp (i, j) the pair (i', j) is also valid and at least as wide. So the only left-endpoint candidates are indices that form a strictly decreasing sequence from the start, which we collect in a stack during a left-to-right pass.
Second, for the right endpoint we want the largest possible j, so we scan from right to left. For each j, while nums[j] is at least the value at the top of the stack, that stack index is a valid left endpoint, so we pop it and record the width. The right-to-left order means the first j that satisfies a given left endpoint is the largest such j, so once we pop an index we already have its widest ramp.
Let (i, j) be an optimal ramp. The stack holds index i unless some earlier index i' has `nums[i'] <= nums[i]`, but then (i', j) is valid and wider, contradicting optimality. So i is on the stack, and the right-to-left scan reaches j before any smaller j, recording the full width j - i* before that left endpoint is popped.
i onto the stack only if nums[i] is strictly less than nums[stack.top()] (or the stack is empty).maxWidth = 0.nums[j] >= nums[stack.top()]:i from the stack.maxWidth = max(maxWidth, j - i).maxWidth.Loading animation...