Program to find maximum width ramp in Python

A ramp in an array is a pair of indices (i, j) where i < j and nums[i] ≤ nums[j]. The width of a ramp is the difference (j - i). We need to find the maximum width ramp in the given array.

For example, in the array [6,0,8,2,1,5], the maximum width ramp is at indices (1, 5) where nums[1] = 0 and nums[5] = 5, giving us a width of 4.

Approach

The solution uses a value-to-indices mapping approach ?

  1. Group indices by their values in a dictionary
  2. Process values in sorted order to find minimum starting indices
  3. Process values in reverse order to find maximum ending indices
  4. Calculate the maximum difference between corresponding positions

Implementation

def solve(nums):
    # Create a dictionary to store indices for each value
    value_indices = {}
    for i in range(len(nums)):
        value = nums[i]
        if value in value_indices:
            value_indices[value].append(i)
        else:
            value_indices[value] = [i]
    
    # Track minimum indices from left for each sorted value
    min_indices = [float('inf')]
    for value in sorted(value_indices.keys()):
        min_indices.append(min(min_indices[-1], min(value_indices[value])))
    
    # Track maximum indices from right for each reverse sorted value
    max_indices = [float('-inf')]
    for value in sorted(value_indices.keys(), reverse=True):
        max_indices.append(max(max_indices[-1], max(value_indices[value])))
    
    # Reverse and trim the max_indices array
    max_indices = max_indices[::-1][:-1]
    # Remove the first element from min_indices
    min_indices = min_indices[1:]
    
    # Find the maximum width ramp
    max_width = float('-inf')
    for i in range(len(min_indices)):
        max_width = max(max_width, max_indices[i] - min_indices[i])
    
    return max_width

# Test the function
nums = [6, 0, 8, 2, 1, 5]
result = solve(nums)
print(f"Maximum width ramp: {result}")
Maximum width ramp: 4

How It Works

Let's trace through the example [6,0,8,2,1,5] ?

def solve_with_trace(nums):
    print(f"Input array: {nums}")
    
    # Step 1: Group indices by values
    value_indices = {}
    for i in range(len(nums)):
        value = nums[i]
        if value in value_indices:
            value_indices[value].append(i)
        else:
            value_indices[value] = [i]
    
    print(f"Value to indices mapping: {value_indices}")
    
    # Step 2: Find minimum indices for sorted values
    min_indices = [float('inf')]
    sorted_values = sorted(value_indices.keys())
    print(f"Sorted values: {sorted_values}")
    
    for value in sorted_values:
        min_idx = min(min_indices[-1], min(value_indices[value]))
        min_indices.append(min_idx)
        print(f"Value {value}: min_index = {min_idx}")
    
    return max(4, 0)  # Simplified for demonstration

# Test with trace
nums = [6, 0, 8, 2, 1, 5]
solve_with_trace(nums)
Input array: [6, 0, 8, 2, 1, 5]
Value to indices mapping: {6: [0], 0: [1], 8: [2], 2: [3], 1: [4], 5: [5]}
Sorted values: [0, 1, 2, 5, 6, 8]
Value 0: min_index = 1
Value 1: min_index = 1
Value 2: min_index = 1
Value 5: min_index = 1
Value 6: min_index = 0
Value 8: min_index = 0

Alternative Approach Using Stack

A more intuitive solution uses a decreasing stack ?

def max_width_ramp_stack(nums):
    # Build decreasing stack of indices
    stack = []
    for i in range(len(nums)):
        if not stack or nums[i] < nums[stack[-1]]:
            stack.append(i)
    
    max_width = 0
    # Scan from right to left
    for j in range(len(nums) - 1, -1, -1):
        while stack and nums[stack[-1]] <= nums[j]:
            i = stack.pop()
            max_width = max(max_width, j - i)
    
    return max_width

# Test both approaches
nums = [6, 0, 8, 2, 1, 5]
print(f"Original approach: {solve(nums)}")
print(f"Stack approach: {max_width_ramp_stack(nums)}")
Original approach: 4
Stack approach: 4

Comparison

Approach Time Complexity Space Complexity Readability
Value Mapping O(n log n) O(n) Complex
Decreasing Stack O(n) O(n) Simple

Conclusion

The stack-based approach is more efficient with O(n) time complexity and easier to understand. It maintains potential starting points in decreasing order and finds the maximum width by scanning from right to left.

Updated on: 2026-03-26T14:13:35+05:30

393 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements