DSA Stacks

Maximum Width Ramp

Build a decreasing-index stack on left pass; right-to-left, pop while top is less-equal current and record gap.

Medium
Time O(n) Space O(n)
LeetCode
4 min read
monotonic-stack two-pointers

Problem#

A ramp is a pair (i, j) with i < j and nums[i] <= nums[j]. Return the maximum width j - i over all ramps, or 0 if none exists.

Examples#

  • nums = [6,0,8,2,1,5]4 (i=1, j=5)
  • nums = [9,8,1,0,1,9,4,0,4,1]7 (i=2, j=9)

Constraints#

  • 2 <= nums.length <= 5 * 10^4, 0 <= nums[i] <= 5 * 10^4.

Approach#

Forward pass: push indices i where nums[i] is strictly less than every previously pushed value — i.e., maintain a stack of “potential left endpoints” with strictly decreasing values. Backward pass: for each j from right to left, pop the top while nums[top] <= nums[j] and update the answer with j - top. Because the stack is decreasing, popping in this way greedily finds the widest legal left for each j.

Solution#

Maximum Width Ramp
class Solution {
public:
int maxWidthRamp(vector<int>& nums) {
int n = nums.size();
stack<int> st;
for (int i = 0; i < n; ++i) {
if (st.empty() || nums[st.top()] > nums[i]) st.push(i);
}
int ans = 0;
for (int j = n - 1; j >= 0; --j) {
while (!st.empty() && nums[st.top()] <= nums[j]) {
ans = max(ans, j - st.top());
st.pop();
}
}
return ans;
}
};

Editorial#

Any optimal left endpoint must be a “decreasing-stack candidate”: if there’s a smaller-or-equal element with a smaller index, that one is strictly better. Sweeping j from the right and popping the stack is then a single linear pass — each index is pushed and popped at most once.

Complexity#

  • Time: O(n).
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.