Problem overview
The function can_jump receives a vector of hurdle heights, hurdle_heights, and the jumper's jump height, jumper_height. It returns true if the jumper can clear every hurdle and false otherwise. A hurdle is cleared when the jump height is greater than or equal to the hurdle's height, so a jump of 5 clears a hurdle of height 5.
Examples: heights [1, 2, 3, 4, 5] with a jump of 5 give true. Heights [5, 5, 3, 4, 5] with a jump of 3 give false, because the first hurdle is 5. Heights [1, 2, 1] with a jump of 1 give false, because the hurdle of height 2 is too tall. An empty vector gives true: with no hurdles, there is nothing to fail.
Approach: look for one failure
"Clears all hurdles" fails as soon as a single hurdle is too tall, so it is easier to search for a counterexample than to confirm each hurdle. Walk through the heights. If a hurdle is taller than the jump, the answer is false immediately. If the walk finishes without finding such a hurdle, every one was clearable and the answer is true.
This also explains the empty case. With no hurdles the loop doesn't run, no counterexample exists, and the function returns true, exactly as the task wants, with no special code.
Step by step
- Loop over
&hurdle_heightswith the variableh. The&borrows the vector, and eachhis a reference to a height. - Test for a hurdle that is too tall with
*h > jumper_height. The comparison is strict: a hurdle exactly as tall as the jump can still be cleared. The*reads the number behind the reference. - Return
falseinside that branch. The first hurdle that is too tall settles the answer, and the rest need no checking. - Return
trueafter the loop. It runs only if no hurdle was too tall.
The solution in Rust
impl Solution {
fn can_jump(hurdle_heights: Vec<i32>, jumper_height: i32) -> bool {
for h in &hurdle_heights {
if *h > jumper_height {
return false;
}
}
return true;
}
}
The Rust details behind it:
- The reference and the dereference. Looping over
&hurdle_heightsgives&i32values. Comparing a reference with ani32does not compile, so the test is*h > jumper_height. - Strict versus non-strict. The failure test is
>, which is the opposite of the success rule "jump height greater than or equal to the hurdle". Using>=here would reject hurdles that are exactly as tall as the jump, so[1, 2, 3, 4, 5]with a jump of 5 would wrongly givefalse. - Return from inside a loop.
returnends the function, not just the loop. After it, the remaining hurdles are never examined. - The final
true. The function must produce aboolon every path, and the loop itself evaluates to(), so the closingreturn true;is required.
Complexity
Time: O(n) for n hurdles. In the worst case, every hurdle is checked once. A tall hurdle near the front lets the function stop early.
Space: O(1), because only a reference to the current height is stored.
Edge cases and common mistakes
- Empty vector. The loop is skipped and the function returns
true. - Equal heights. A hurdle with the same height as the jump is cleared.
[5, 4, 5, 6]with a jump of 6 givestrue. - Returning
trueinside the loop. A hurdle that can be cleared proves nothing about the next one. Returningtruethere would answer after the first small hurdle. - Swapping the arguments in the comparison. The test compares a hurdle with the jump height, in that order. Reversing them reverses the meaning.
- Only checking the last or first hurdle. The tall hurdle can be anywhere, as in
[1, 9, 1]with a jump of 5, which givesfalse.
Testing
[1, 2, 3, 4, 5]with 5 givestrue.[5, 5, 3, 4, 5]with 3 givesfalse.[5, 4, 5, 6]with 10 givestrue.[1, 2, 1]with 1 givesfalse.[]with 0 givestrue.
