Solved game jump from leet code
This commit is contained in:
commit
39c3fae613
5 changed files with 140 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "jump_game"
|
||||
version = "0.1.0"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "jump_game"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
123
src/lib.rs
Normal file
123
src/lib.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
struct Solution;
|
||||
|
||||
// Copy from here for submitting this solution to leet code
|
||||
impl Solution {
|
||||
pub fn can_jump(nums: Vec<i32>) -> bool {
|
||||
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
|
||||
pub fn idiom_can_jump(nums: &[i32]) -> bool {
|
||||
if nums.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let target_val = (nums.len() - 1) as i32;
|
||||
let mut next_nodes = Vec::from([(0, nums[0])]);
|
||||
// index visited yet
|
||||
let mut visted_indices = -1;
|
||||
if Self::check_with_target_value(target_val, 0) {
|
||||
return true;
|
||||
}
|
||||
while let Some(next_node) = next_nodes.pop() {
|
||||
let (index, steps) = next_node;
|
||||
let max_jump_height = index + steps;
|
||||
if Self::check_with_target_value(target_val, max_jump_height) {
|
||||
return true;
|
||||
}
|
||||
// It can start at 1 because the every index was checked in previous path walking
|
||||
for next_to_check in 1..=steps {
|
||||
let to_add = index + next_to_check;
|
||||
if visted_indices >= to_add {
|
||||
// already visited this index
|
||||
continue;
|
||||
}
|
||||
visted_indices = to_add;
|
||||
next_nodes.push((to_add, nums[to_add as usize]));
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
fn check_with_target_value(target: i32, value: i32) -> bool {
|
||||
target <= value
|
||||
}
|
||||
}
|
||||
// Stop copying from here for submitting this solution to leet code
|
||||
|
||||
#[cfg(test)]
|
||||
mod testing {
|
||||
use crate::Solution;
|
||||
|
||||
#[test]
|
||||
fn empty_input() {
|
||||
let given = vec![];
|
||||
let expected = false;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jumping_no_matter_because_one_element() {
|
||||
let given = vec![0];
|
||||
let expected = true;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
//Input: nums = [2,3,1,1,4]
|
||||
//Output: true
|
||||
//Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
|
||||
fn jump_possible() {
|
||||
// Example 1:
|
||||
//
|
||||
let given = vec![2, 3, 1, 1, 4];
|
||||
let expected = true;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
//Example 2:
|
||||
//
|
||||
//Input: nums = [3,2,1,0,4]
|
||||
//Output: false
|
||||
#[test]
|
||||
fn no_jump_possible() {
|
||||
let given = vec![3, 2, 1, 0, 4];
|
||||
let expected = false;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jump_two_elements() {
|
||||
let given = vec![2, 0];
|
||||
let expected = true;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_jump_complex_array() {
|
||||
let given = vec![3, 0, 8, 2, 0, 0, 1];
|
||||
let expected = true;
|
||||
assert_case(given, expected);
|
||||
}
|
||||
|
||||
fn assert_case(given: Vec<i32>, expected: bool) {
|
||||
let actual = Solution::idiom_can_jump(&given);
|
||||
assert_eq!(expected, actual, "Given input: {:#?}", &given);
|
||||
}
|
||||
}
|
3
src/main.rs
Normal file
3
src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Add table
Reference in a new issue