From 4def379400ba1fafda214249cedde3c4606a5f02 Mon Sep 17 00:00:00 2001 From: boolpurist Date: Tue, 6 Aug 2024 14:25:26 +0200 Subject: [PATCH] Cut out not needed intial if statement and reduced space usage --- README.md | 1 + src/lib.rs | 73 ++++++++++++++++++++++++------------------------------ 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index e0e55b5..e96ae52 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,4 @@ and failed submissions of previously flawed solutions. ## Status This solution passes the submission + diff --git a/src/lib.rs b/src/lib.rs index 2d6af95..df90577 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,62 +8,55 @@ impl Solution { Solution::idiom_can_jump(&nums) } - /// - /// ## Mapping elements to nodes in a graph - /// Every index is viewed as a node in a graph. - /// The value of a node (value of the element in the array) - /// is the number of edges to subsequent successors. - /// - /// ### 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 + /// Returns true if the last element can be reached + /// by starting with the 0th element in accordance to the rules of the jump game. + /// Link to the description of this code challenge. + /// https://leetcode.com/problems/jump-game/description/ + /// Source code of this solution is hosted on: + /// https://git.kb-one.de/boolpurist/jump_game_challenge_solution/src/branch/main/src/lib.rs pub fn idiom_can_jump(nums: &[i32]) -> bool { if nums.is_empty() { return false; } + // parameter can not be empty at this point let target_val = (nums.len() - 1) as i32; // Using a dequeue ensures that every index is visited - let mut next_nodes = VecDeque::from([(0, nums[0])]); - // index visited yet - let mut greatest_visited_indices = -1; - if Self::check_with_target_value(target_val, 0) { - return true; - } - while let Some(next_node) = next_nodes.pop_front() { - let (index, steps) = next_node; - let max_jump_height = index + steps; - if Self::check_with_target_value(target_val, max_jump_height) { + // Reason: This algorithm finds every index in an ascending order. + // Dequeue acts here as a queue preserving the ascending order in which the indices are + // found + let mut next_nodes = VecDeque::from([0]); + // This index and all previous ones are visited already + let mut greatest_visited_index = 0; + while let Some(next_index) = next_nodes.pop_front() { + // Indexing with a next_index greater than the length + // of parameter nums will not happen + // 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; } // Going left to right and using a dequeue for FIFO access, // all indices are visited - let start_point = greatest_visited_indices + 1; - // It can start at greatest_visited_indices + 1 because the every index was checked - // in previous iterations. + let not_visited = greatest_visited_index + 1; + // It can start at greatest_visited_indices + 1 because the every index was inpected + // in a previous iterations. // If the max_jump_height is lower than the start_point // then there is not new index to be discovered - for to_add in start_point..=max_jump_height { - if to_add > greatest_visited_indices { - next_nodes.push_back((to_add, nums[to_add as usize])); - greatest_visited_indices = to_add; - } + let last_unvisited = max_jump_height + 1; + // This loops grantees that every reachable index is visited and only once + // in the worst case scenario + // 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 } - fn check_with_target_value(target: i32, value: i32) -> bool { - target <= value - } } // Stop copying from here for submitting this solution to leet code