Compare commits

..

2 commits

Author SHA1 Message Date
boolpurist
a50f956cfb Added current best under leet code 2024-08-06 14:29:26 +02:00
boolpurist
4def379400 Cut out not needed intial if statement and reduced space usage 2024-08-06 14:25:26 +02:00
3 changed files with 37 additions and 40 deletions

View file

@ -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
![current_best_on_leet_code](./pics/current_best_on_leet_code.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -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