1936. Add Minimum Number of Rungs
Problem Description
You start at height 0 (the floor) and need to climb a ladder to reach the last rung. The ladder has rungs at specific heights given in the array rungs
, which is strictly increasing.
You have a maximum step distance dist
- this means you can only climb from your current position to the next rung if the height difference is at most dist
. If the next rung is too far (height difference > dist
), you need to add intermediate rungs to make the climb possible.
The key rules are:
- You start at height 0 (the floor)
- You can only step up by at most
dist
units at a time - You can insert new rungs at any positive integer height where a rung doesn't already exist
- You want to reach the last rung in the
rungs
array
The goal is to find the minimum number of rungs you need to add to make it possible to climb from the floor to the last rung.
For example, if rungs = [3, 6, 8, 10]
and dist = 3
:
- From floor (0) to rung at height 3: distance is 3, which equals
dist
, so no additional rungs needed - From height 3 to height 6: distance is 3, which equals
dist
, so no additional rungs needed - From height 6 to height 8: distance is 2, which is less than
dist
, so no additional rungs needed - From height 8 to height 10: distance is 2, which is less than
dist
, so no additional rungs needed - Total additional rungs needed: 0
The solution uses the formula β(b - a - 1) / distβ
to calculate how many rungs need to be inserted between position a
and position b
when the distance exceeds dist
.
Intuition
The key insight is that we want to minimize the number of rungs added, so we should only add rungs when absolutely necessary. When do we need to add rungs? Only when the gap between our current position and the next rung exceeds our maximum step distance dist
.
Think about it greedily: if we're at position a
and need to reach position b
where b - a > dist
, we want to take the largest possible steps of size dist
each time. This means we should place new rungs at positions a + dist
, a + 2*dist
, a + 3*dist
, and so on, until we can reach b
.
How many such rungs do we need? If the gap is b - a
, we need to divide this gap into chunks of size dist
. However, we don't need to add a rung at position b
since it already exists. So we're really asking: how many complete steps of size dist
fit in the gap b - a - 1
?
This gives us the formula β(b - a - 1) / distβ
:
b - a
is the total gap- We subtract 1 because if the gap is exactly divisible by
dist
, we don't need an extra rung (we can reachb
directly) - Integer division gives us the number of complete
dist
-sized steps we need to insert
For example, if the gap is 10 and dist = 3
:
- We need rungs at positions +3, +6, +9 from our current position
- That's 3 rungs, which equals
β(10 - 1) / 3β = β9 / 3β = 3
We apply this calculation to each consecutive pair of positions (including from the floor at height 0 to the first rung), and sum up all the required rungs.
Learn more about Greedy patterns.
Solution Approach
The implementation follows a greedy simulation approach. We process each gap between consecutive positions and calculate how many rungs need to be inserted.
Step 1: Prepare the data
- We prepend 0 to the
rungs
array to represent the floor:rungs = [0] + rungs
- This allows us to treat the problem uniformly - every climb is from one position to the next, including the initial climb from the floor
Step 2: Process consecutive pairs
- We use
pairwise(rungs)
to iterate through consecutive pairs(a, b)
where:a
is the current positionb
is the next rung we want to reach
Step 3: Calculate rungs needed for each gap
- For each pair
(a, b)
, we calculate the number of rungs to insert using the formula:(b - a - 1) // dist
- This formula works because:
- If
b - a <= dist
, the formula gives 0 (no rungs needed) - If
b - a > dist
, we needβ(b - a - 1) / distβ
intermediate rungs
- If
Step 4: Sum up all insertions
- We use Python's
sum()
function with a generator expression to calculate the total number of rungs needed across all gaps
Example walkthrough:
If rungs = [3, 6, 8, 10]
and dist = 2
:
- After prepending:
[0, 3, 6, 8, 10]
- Pairs:
(0,3)
,(3,6)
,(6,8)
,(8,10)
- Calculations:
- Gap 0β3:
(3-0-1)//2 = 2//2 = 1
rung needed - Gap 3β6:
(6-3-1)//2 = 2//2 = 1
rung needed - Gap 6β8:
(8-6-1)//2 = 1//2 = 0
rungs needed - Gap 8β10:
(10-8-1)//2 = 1//2 = 0
rungs needed
- Gap 0β3:
- Total:
1 + 1 + 0 + 0 = 2
rungs
The time complexity is O(n) where n is the length of the rungs array, and the space complexity is O(1) if we don't count the space used for the modified input.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example with rungs = [4, 8, 12, 16]
and dist = 3
.
Initial Setup:
- We start at height 0 (the floor)
- We need to reach the last rung at height 16
- We can only step up by at most 3 units at a time
Step 1: Prepare the data
- Prepend 0 to represent the floor:
[0, 4, 8, 12, 16]
- This gives us pairs:
(0,4)
,(4,8)
,(8,12)
,(12,16)
Step 2: Process each gap
Gap 1: From floor (0) to first rung (4)
- Distance: 4 - 0 = 4
- Since 4 > 3 (our max step), we need intermediate rungs
- Apply formula:
(4 - 0 - 1) // 3 = 3 // 3 = 1
- We need 1 additional rung (placed at height 3)
- Path: 0 β 3 (added) β 4
Gap 2: From height 4 to height 8
- Distance: 8 - 4 = 4
- Since 4 > 3, we need intermediate rungs
- Apply formula:
(8 - 4 - 1) // 3 = 3 // 3 = 1
- We need 1 additional rung (placed at height 7)
- Path: 4 β 7 (added) β 8
Gap 3: From height 8 to height 12
- Distance: 12 - 8 = 4
- Since 4 > 3, we need intermediate rungs
- Apply formula:
(12 - 8 - 1) // 3 = 3 // 3 = 1
- We need 1 additional rung (placed at height 11)
- Path: 8 β 11 (added) β 12
Gap 4: From height 12 to height 16
- Distance: 16 - 12 = 4
- Since 4 > 3, we need intermediate rungs
- Apply formula:
(16 - 12 - 1) // 3 = 3 // 3 = 1
- We need 1 additional rung (placed at height 15)
- Path: 12 β 15 (added) β 16
Step 3: Calculate total
- Total rungs needed: 1 + 1 + 1 + 1 = 4
Final climbing path: 0 β 3 β 4 β 7 β 8 β 11 β 12 β 15 β 16
The formula (b - a - 1) // dist
elegantly handles all cases:
- When the gap equals
dist + 1
(like 4 in our example), we need exactly 1 rung - When the gap is less than or equal to
dist
, the formula gives 0 - For larger gaps, it calculates the exact number of intermediate steps needed
Solution Implementation
1class Solution:
2 def addRungs(self, rungs: List[int], dist: int) -> int:
3 # Add starting position 0 to the beginning of rungs list
4 rungs = [0] + rungs
5
6 # Calculate total number of additional rungs needed
7 total_additional_rungs = 0
8
9 # Iterate through consecutive pairs of rungs
10 for i in range(len(rungs) - 1):
11 current_rung = rungs[i]
12 next_rung = rungs[i + 1]
13
14 # Calculate the gap between consecutive rungs
15 gap = next_rung - current_rung
16
17 # Calculate number of additional rungs needed for this gap
18 # If gap <= dist, no additional rungs needed (result is 0)
19 # Otherwise, we need (gap - 1) // dist additional rungs
20 additional_rungs_needed = (gap - 1) // dist
21
22 total_additional_rungs += additional_rungs_needed
23
24 return total_additional_rungs
25
1class Solution {
2 public int addRungs(int[] rungs, int dist) {
3 // Initialize counter for additional rungs needed
4 int additionalRungs = 0;
5
6 // Track the previous rung position (starting from ground at 0)
7 int previousPosition = 0;
8
9 // Iterate through each rung in the ladder
10 for (int currentRung : rungs) {
11 // Calculate the gap between current and previous rung
12 int gap = currentRung - previousPosition;
13
14 // Calculate how many additional rungs are needed to bridge the gap
15 // Formula: (gap - 1) / dist gives the number of intermediate rungs needed
16 // We subtract 1 because we can make a jump of exactly 'dist' without adding a rung
17 additionalRungs += (gap - 1) / dist;
18
19 // Update previous position to current rung for next iteration
20 previousPosition = currentRung;
21 }
22
23 return additionalRungs;
24 }
25}
26
1class Solution {
2public:
3 int addRungs(vector<int>& rungs, int dist) {
4 // Initialize counter for additional rungs needed
5 int additionalRungs = 0;
6
7 // Track the previous rung position (starting from ground at 0)
8 int previousPosition = 0;
9
10 // Iterate through each rung in the ladder
11 for (int& currentRung : rungs) {
12 // Calculate the gap between current and previous rung
13 int gap = currentRung - previousPosition;
14
15 // Calculate how many additional rungs are needed to bridge the gap
16 // Formula: (gap - 1) / dist gives the number of intermediate rungs needed
17 // We subtract 1 because we can reach exactly 'dist' units without adding a rung
18 additionalRungs += (gap - 1) / dist;
19
20 // Update previous position for next iteration
21 previousPosition = currentRung;
22 }
23
24 return additionalRungs;
25 }
26};
27
1/**
2 * Calculates the minimum number of rungs to add so that the maximum distance between
3 * consecutive rungs (including ground at 0) does not exceed the given distance.
4 *
5 * @param rungs - Array of heights representing existing rungs in ascending order
6 * @param dist - Maximum allowed distance between consecutive rungs
7 * @returns The minimum number of rungs that need to be added
8 */
9function addRungs(rungs: number[], dist: number): number {
10 // Total number of rungs to be added
11 let additionalRungs: number = 0;
12
13 // Previous rung position (starting from ground at 0)
14 let previousPosition: number = 0;
15
16 // Iterate through each existing rung
17 for (const currentRung of rungs) {
18 // Calculate the gap between current and previous position
19 const gap: number = currentRung - previousPosition;
20
21 // Calculate how many rungs needed to fill the gap
22 // Using (gap - 1) / dist gives us the number of additional rungs needed
23 // The bitwise OR with 0 performs integer division (floor)
24 const rungsNeededInGap: number = ((gap - 1) / dist) | 0;
25
26 // Add the required rungs to our total count
27 additionalRungs += rungsNeededInGap;
28
29 // Update previous position for next iteration
30 previousPosition = currentRung;
31 }
32
33 return additionalRungs;
34}
35
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the rungs
list. This is because:
- Creating
[0] + rungs
takesO(n)
time to create a new list - The
pairwise(rungs)
function iterates through the list once, generatingn
pairs - The
sum()
function with the generator expression iterates through all pairs once, performingO(1)
arithmetic operations for each pair
The space complexity is O(n)
, not O(1)
as stated in the reference answer. This is because:
- The operation
[0] + rungs
creates a new list of sizen + 1
, which requiresO(n)
additional space - The
pairwise()
function returns an iterator that doesn't require additional space beyondO(1)
- The generator expression
(b - a - 1) // dist for a, b in pairwise(rungs)
usesO(1)
space
The reference answer's claim of O(1)
space complexity would only be correct if the code modified the original list in-place or used a different approach that avoided creating a new list.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Consider the Starting Position (Floor)
Many solutions incorrectly calculate the distance from the first rung without considering that you start at height 0. This leads to missing additional rungs needed for the initial climb.
Incorrect approach:
def addRungs(self, rungs: List[int], dist: int) -> int:
total = 0
# Wrong: only checking gaps between existing rungs
for i in range(len(rungs) - 1):
gap = rungs[i + 1] - rungs[i]
total += (gap - 1) // dist
return total
Why it fails: If rungs = [4, 8, 12]
and dist = 2
, this would miss that climbing from floor (0) to height 4 requires additional rungs.
Solution: Always include the starting position 0 in your calculations, either by prepending it to the array or handling the first rung separately.
2. Using the Wrong Formula for Calculating Additional Rungs
A common mistake is using gap // dist
instead of (gap - 1) // dist
.
Incorrect formula:
additional_rungs = gap // dist # Wrong!
Why it fails: When the gap is exactly divisible by dist
, this formula gives one extra rung. For example, if gap = 6 and dist = 3, we can climb in exactly 2 steps (0β3β6), needing only 1 additional rung. But 6 // 3 = 2
would suggest we need 2 additional rungs.
Correct formula:
additional_rungs = (gap - 1) // dist
This works because:
- If
gap <= dist
:(gap - 1) // dist = 0
(no additional rungs needed) - If
gap > dist
: We need exactlyβ(gap - 1) / distβ
intermediate rungs
3. Off-by-One Errors in Loop Iteration
When iterating through pairs, it's easy to create index out of bounds errors.
Incorrect approach:
for i in range(len(rungs)): # Wrong: will cause index error
gap = rungs[i + 1] - rungs[i]
Solution: Use range(len(rungs) - 1)
or better yet, use Python's pairwise
function from itertools for cleaner code:
from itertools import pairwise for current, next_rung in pairwise([0] + rungs): gap = next_rung - current total += (gap - 1) // dist
Which algorithm should you use to find a node that is close to the root of the tree?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Donβt Miss This!