2022-07-13:給你一個整數陣列 arr ,你一開始在陣列的第一個元素處(下標為 0)。 每一步

moonfdd發表於2022-07-13

2022-07-13:給你一個整數陣列 arr ,你一開始在陣列的第一個元素處(下標為 0)。
每一步,你可以從下標 i 跳到下標 i + 1 、i - 1 或者 j :
i + 1 需滿足:i + 1 < arr.length,
i - 1 需滿足:i - 1 >= 0,
j 需滿足:arr[i] == arr[j] 且 i != j。
請你返回到達陣列最後一個元素的下標處所需的 最少操作次數 。
注意:任何時候你都不能跳到陣列外面。
來自蔚來汽車。

答案2022-07-13:

存在左跳的可能。寬度優先遍歷,層次遍歷。

程式碼用rust編寫。程式碼如下:

use std::collections::HashMap;
fn main() {
    let mut arr: Vec<i32> = vec![100, -23, -23, 404, 100, 23, 23, 23, 3, 404];
    let ans = min_jumps(&mut arr);
    println!("ans = {}", ans);
}

fn min_jumps(arr: &mut Vec<i32>) -> i32 {
    let n = arr.len() as i32;
    // 為了找某個值,有哪些位置,能快一些
    // key : 某個值9,
    // value : 列表:0,7,19
    let mut value_index: HashMap<i32, Vec<i32>> = HashMap::new();
    for i in 0..n {
        if !value_index.contains_key(&arr[i as usize]) {
            value_index.insert(arr[i as usize], vec![]);
        }
        value_index.get_mut(&arr[i as usize]).unwrap().push(i);
    }
    // i會有哪些展開:左,右,i透過自己的值,能蹦到哪些位置上去
    // 寬度優先遍歷,遍歷過的位置,不希望重複處理
    // visited[i] == false:i位置,之前沒來過,可以處理
    // visited[i] == true : i位置,之前來過,可以跳過
    let mut visited: Vec<bool> = vec![];
    for _ in 0..n {
        visited.push(false);
    }
    let mut queue: Vec<i32> = vec![];
    for _ in 0..n {
        queue.push(0);
    }
    let mut l: i32 = 0;
    let mut r: i32 = 0;
    // 0位置加到佇列裡去
    queue[r as usize] = 0;
    r += 1;
    visited[0] = true;
    let mut jump = 0;
    // 寬度優先遍歷
    // 一次,遍歷一整層!
    // 該技巧,多次出現!
    while l != r {
        // 佇列裡還有東西的意思!
        // 此時的r記錄!
        // 0 1 2 | 3 4 5 6 7 8
        // 當前層的終止位置
        let tmp = r;
        while l < tmp {
            // 遍歷當前層!
            let cur = queue[l as usize];
            if cur == n - 1 {
                return jump;
            }
            if cur + 1 < n && !visited[(cur + 1) as usize] {
                visited[(cur + 1) as usize] = true;
                queue[r as usize] = cur + 1;
                r += 1;
            }
            // cur > 0  cur - 1 >=0
            if cur > 0 && !visited[(cur - 1) as usize] {
                visited[(cur - 1) as usize] = true;
                queue[r as usize] = cur - 1;
                r += 1;
            }
            // i -> 9
            // 值同樣為9的那些位置,也能去
            for next in value_index.get(&arr[cur as usize]).unwrap().iter() {
                if !visited[*next as usize] {
                    visited[*next as usize] = true;
                    queue[r as usize] = *next;
                    r += 1;
                }
            }
            // 重要最佳化!
            value_index.insert(arr[cur as usize], vec![]);
            l += 1;
        }
        jump += 1;
    }
    return -1;
}

執行結果如下:

在這裡插入圖片描述


左神java程式碼

本作品採用《CC 協議》,轉載必須註明作者和本文連結
微信公眾號:福大大架構師每日一題。最新面試題,涉及golang,rust,mysql,redis,雲原生,演算法,分散式,網路,作業系統。

相關文章