2022-07-11:給定n位長的數字字串和正數k,求該子符串能被k整除的子串個數。 (n<=1000,k<=100)

moonfdd發表於2022-07-11

2022-07-11:給定n位長的數字字串和正數k,求該子符串能被k整除的子串個數。
(n<=1000,k<=100)。
來自微眾。4.11筆試。

答案2022-07-11:

動態規劃。假設abcdef%k=0,abc000%k=0,那麼def%k=0。

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

use rand::Rng;
fn main() {
    let nn: i64 = 18;
    let kk: i64 = 20;
    let test_time: i32 = 3000;
    println!("測試開始");
    for i in 0..test_time {
        let str = random_number(rand::thread_rng().gen_range(0, nn) + 1);
        let k = rand::thread_rng().gen_range(0, kk) + 1;
        let ans1 = mod_ways1(&str, k);
        let ans2 = mod_ways2(&str, k);
        if ans1 != ans2 {
            println!("出錯了!{}", i);
            println!("ans1 = {}", ans1);
            println!("ans2 = {}", ans2);
            break;
        }
    }
    println!("測試結束");
}

// 暴力方法
// 為了驗證
fn mod_ways1(s: &str, k: i64) -> i64 {
    let n = s.len() as i64;
    let mut ans = 0;
    for i in 0..n {
        for j in i..n {
            if (&s[i as usize..(j + 1) as usize]).parse::<i64>().unwrap() % k == 0 {
                ans += 1;
            }
        }
    }
    return ans;
}

// 正式方法
// 時間複雜度O(N * k)
fn mod_ways2(s: &str, k: i64) -> i64 {
    let mut cur: Vec<i64> = vec![];
    for _ in 0..k {
        cur.push(0);
    }
    // 幫忙遷移
    let mut next: Vec<i64> = vec![];
    for _ in 0..k {
        next.push(0);
    }
    // 0...i 整體餘幾?
    let mut mod0: i64 = 0;
    // 答案:統計有多少子串的值%k == 0
    let mut ans = 0;
    for cha in s.bytes() {
        for i in 0..k {
            // i -> 10個
            // (i * 10) % k
            next[((i * 10) % k) as usize] += cur[i as usize];
            cur[i as usize] = 0;
        }
        let mut tmp = cur.clone();
        cur = next.clone();
        next = tmp.clone();
        mod0 = (mod0 * 10 + (cha - '0' as u8) as i64) % k;
        ans += if mod0 == 0 { 1 } else { 0 } + cur[mod0 as usize];
        cur[mod0 as usize] += 1;
    }
    return ans;
}

// 為了測試
fn random_number(n: i64) -> String {
    let mut ans: Vec<u8> = vec![];
    for _i in 0..n {
        ans.push('0' as u8 + rand::thread_rng().gen_range(0, 10));
    }
    return String::from_utf8(ans).unwrap();
}

執行結果如下:

在這裡插入圖片描述


左神java程式碼

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

相關文章