diff --git a/src/main.rs b/src/main.rs index 362c93c..da55005 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,105 @@ mod arr; - struct Solution {} -impl Solution { - pub fn rotated_digits(n: i32) -> i32 { - let mut ans = 0; - let check = |mut x: i32| -> bool { - let mut is_diff = false; - while x != 0 { - let y = x % 10; - match y { - 2 => is_diff = true, - 3 => return false, - 4 => return false, - 5 => is_diff = true, - 6 => is_diff = true, - 7 => return false, - 9 => is_diff = true, - _ => {} - } - x /= 10; + +use std::cmp::Ordering; +use std::collections::{BinaryHeap, HashMap}; + +#[derive(Eq, PartialEq)] +struct Item(usize, usize); // (键, 值) +impl Ord for Item { + fn cmp(&self, other: &Self) -> Ordering { + other.0.cmp(&self.0) // 反序,实现最小堆 + } +} + +impl PartialOrd for Item { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +static mut IS_PRIME: Vec> = vec![]; + +pub fn get_is_prime() -> fn(i32) -> &'static Vec { + unsafe { + #![allow(static_mut_refs)] + if IS_PRIME.is_empty() { + let n = 1e6 as usize; + IS_PRIME = vec![vec![]; n + 1]; + for i in 2..n + 1 { + IS_PRIME[i].push(1); + IS_PRIME[i].push(i as i32); + } + let mut primes = vec![0; n + 1]; + let mut cnt = 0; + + for i in 2..=n { + if IS_PRIME[i].len() == 2 + //是素数采用来筛 + { + cnt += 1; + primes[cnt] = i; //加入素数表 + for j in (2 * i..=n).step_by(i) { + IS_PRIME[j].push(i as i32); + } + } } - is_diff - }; - for i in 1..=n { - ans += if check(i) { 1 } else { 0 } } - ans + } + + // 返回函数指针,访问时再用 unsafe + fn check(x: i32) -> &'static Vec { + unsafe { &IS_PRIME[x as usize] } + } + + check +} + +impl Solution { + pub fn min_jumps(nums: Vec) -> i32 { + let mut arr = vec![1e6 as usize; nums.len()]; + let mut map = HashMap::>::new(); + let is_prime = get_is_prime(); + for i in 0..nums.len() { + if is_prime(nums[i]).len() == 2 { + map.entry(nums[i]).or_insert(vec![]).push(i); + } + } + // key 跳数 val 下标 + let mut queue = BinaryHeap::new(); + queue.push(Item(0, nums.len() - 1)); + + arr[nums.len() - 1] = 0; + while let Some(Item(jump_count, index)) = queue.pop() { + if index == 0 { + return jump_count as i32; + } + if index > 0 { + if arr[index - 1] > arr[index] + 1 { + queue.push(Item(jump_count + 1, index - 1)); + arr[index - 1] = jump_count + 1; + } + } + if index < arr.len() - 1 { + if arr[index + 1] > arr[index] + 1 { + queue.push(Item(jump_count + 1, index + 1)); + arr[index + 1] = jump_count + 1; + } + } + + for i in is_prime(nums[index]).iter().skip(1) { + for x in map.entry(*i).or_default() { + if arr[*x] > arr[index] + 1 { + queue.push(Item(jump_count + 1, *x)); + arr[*x] = jump_count + 1; + } + } + map.remove_entry(i); + } + } + 0 } } fn main() { - println!("{:?}", Solution::rotated_digits(10)); + println!("{:?}", Solution::min_jumps(vec![5;1e5 as usize])); }