Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
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 ?
- Group indices by their values in a dictionary
- Process values in sorted order to find minimum starting indices
- Process values in reverse order to find maximum ending indices
- 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.
Advertisements
