Compare commits
2 commits
36ecf4affa
...
a50f956cfb
Author | SHA1 | Date | |
---|---|---|---|
|
a50f956cfb | ||
|
4def379400 |
3 changed files with 37 additions and 40 deletions
|
@ -17,3 +17,7 @@ and failed submissions of previously flawed solutions.
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
This solution passes the submission
|
This solution passes the submission
|
||||||
|
|
||||||
|
Current best on leet code with the commit 4def379400ba1fafda214249cedde3c4606a5f02
|
||||||
|
|
||||||
|

|
||||||
|
|
BIN
pics/current_best_on_leet_code.png
Normal file
BIN
pics/current_best_on_leet_code.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
73
src/lib.rs
73
src/lib.rs
|
@ -8,62 +8,55 @@ impl Solution {
|
||||||
Solution::idiom_can_jump(&nums)
|
Solution::idiom_can_jump(&nums)
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
/// Returns true if the last element can be reached
|
||||||
/// ## Mapping elements to nodes in a graph
|
/// by starting with the 0th element in accordance to the rules of the jump game.
|
||||||
/// Every index is viewed as a node in a graph.
|
/// Link to the description of this code challenge.
|
||||||
/// The value of a node (value of the element in the array)
|
/// https://leetcode.com/problems/jump-game/description/
|
||||||
/// is the number of edges to subsequent successors.
|
/// Source code of this solution is hosted on:
|
||||||
///
|
/// https://git.kb-one.de/boolpurist/jump_game_challenge_solution/src/branch/main/src/lib.rs
|
||||||
/// ### Example
|
|
||||||
/// Given the first element in \[3,2,1,0,4\]
|
|
||||||
///
|
|
||||||
/// This element has two edges, with the second and the third elements as subsequent successors
|
|
||||||
///
|
|
||||||
/// ## Why the mapping to a graph
|
|
||||||
///
|
|
||||||
/// By doing so, one can skip redundant work.
|
|
||||||
/// Redundant work would be walking a path more than once.
|
|
||||||
/// Walking a path is simulating jumping from 1 to the max jump height.
|
|
||||||
/// Path walking checks if any jump height from a certain index will reach the last index.
|
|
||||||
/// Every simulated jump height serves as a next start point for new path walking if this starting
|
|
||||||
/// point was not tried before
|
|
||||||
pub fn idiom_can_jump(nums: &[i32]) -> bool {
|
pub fn idiom_can_jump(nums: &[i32]) -> bool {
|
||||||
if nums.is_empty() {
|
if nums.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// parameter can not be empty at this point
|
||||||
let target_val = (nums.len() - 1) as i32;
|
let target_val = (nums.len() - 1) as i32;
|
||||||
// Using a dequeue ensures that every index is visited
|
// Using a dequeue ensures that every index is visited
|
||||||
let mut next_nodes = VecDeque::from([(0, nums[0])]);
|
// Reason: This algorithm finds every index in an ascending order.
|
||||||
// index visited yet
|
// Dequeue acts here as a queue preserving the ascending order in which the indices are
|
||||||
let mut greatest_visited_indices = -1;
|
// found
|
||||||
if Self::check_with_target_value(target_val, 0) {
|
let mut next_nodes = VecDeque::from([0]);
|
||||||
return true;
|
// This index and all previous ones are visited already
|
||||||
}
|
let mut greatest_visited_index = 0;
|
||||||
while let Some(next_node) = next_nodes.pop_front() {
|
while let Some(next_index) = next_nodes.pop_front() {
|
||||||
let (index, steps) = next_node;
|
// Indexing with a next_index greater than the length
|
||||||
let max_jump_height = index + steps;
|
// of parameter nums will not happen
|
||||||
if Self::check_with_target_value(target_val, max_jump_height) {
|
// Reason: the values for next_index greater than len of nums
|
||||||
|
// are not used for indexing because the check for reaching the last index
|
||||||
|
// is done before using next_index for indexing
|
||||||
|
let jump_height = nums[next_index as usize];
|
||||||
|
let max_jump_height = next_index + jump_height;
|
||||||
|
let found_end_of_seq = target_val <= max_jump_height;
|
||||||
|
if found_end_of_seq {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Going left to right and using a dequeue for FIFO access,
|
// Going left to right and using a dequeue for FIFO access,
|
||||||
// all indices are visited
|
// all indices are visited
|
||||||
let start_point = greatest_visited_indices + 1;
|
let not_visited = greatest_visited_index + 1;
|
||||||
// It can start at greatest_visited_indices + 1 because the every index was checked
|
// It can start at greatest_visited_indices + 1 because the every index was inpected
|
||||||
// in previous iterations.
|
// in a previous iterations.
|
||||||
// If the max_jump_height is lower than the start_point
|
// If the max_jump_height is lower than the start_point
|
||||||
// then there is not new index to be discovered
|
// then there is not new index to be discovered
|
||||||
for to_add in start_point..=max_jump_height {
|
let last_unvisited = max_jump_height + 1;
|
||||||
if to_add > greatest_visited_indices {
|
// This loops grantees that every reachable index is visited and only once
|
||||||
next_nodes.push_back((to_add, nums[to_add as usize]));
|
// in the worst case scenario
|
||||||
greatest_visited_indices = to_add;
|
// This leads to a linear time complexity for comparison done by Self::check_with_target_value
|
||||||
}
|
for to_inspect_later in not_visited..last_unvisited {
|
||||||
|
next_nodes.push_back(to_inspect_later);
|
||||||
|
greatest_visited_index = to_inspect_later;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn check_with_target_value(target: i32, value: i32) -> bool {
|
|
||||||
target <= value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Stop copying from here for submitting this solution to leet code
|
// Stop copying from here for submitting this solution to leet code
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue