rust leetcode 周赛 288

本文作者分享了参与算法竞赛的经验,包括时间管理、错误分析和代码优化方面的心得。提到了使用Rust语言的特定方法,如 `.to_digits(10)` 转换数字,`format!()` 生成格式化字符串,以及如何利用二分查找和堆等数据结构进行高效编程。此外,还展示了几个具体问题的解决方案,涉及数字操作、表达式求解和数组处理等算法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模拟参赛,差不多 2:00:00 做完,严重超时,第三题第四题各wa一发。第一名花了25分钟。

rust snippets:

  1. 单个字符转数字:.to_digits(10),但第一题也可以考虑直接操作字符数组 &str.
  2. format!() 可以方便地生成格式化字符串
  3. std::collections::BinaryHeap 不支持构建时指定排序规则,只支持按元素自带的排序规则返回最大值。如果快速需要一个最小堆,可以使用某个库里的 reverse,安全(是真的,使用 reverse 我能少 wa 一次)。
  4. binary_search 只会返回任意一个匹配到的元素,不实用。partition_point 可以完成所需的二分查找工作,返回第二个分组(满足条件的分组)中的第一个下标,注意越界。

tips:

  • 我最终的二分模版,好写、好理解,不容易错。
    let mut left = ...;
    let mut right = ...;
    let mut last_success = left;
    while left <= right {
       let candidate = (right+left)/2;
       if success(candidate)
           last_success = candidate;
           left = candidate + 1;
       }
       else {
           right = candidate - 1;
       }
    }
    last_success
    
  • 前缀和数组没有前置 0 会很难受,left 和 right 都得设定边界。所以最好加上前置 0.

2231 largest-number-after-digit-swaps-by-parity/

impl Solution {
    pub fn largest_integer(num: i32) -> i32 {
        let mut digits = num.
            to_string().
            chars().
            map(|d| d.to_digit(10).unwrap() as i32).
            collect::<Vec<i32>>();
        
        for i in 0..digits.len() {
            for j in (i+1)..digits.len() {
                if (digits[i]-digits[j])%2==0 && digits[i] < digits[j] {
                    digits.swap(i, j);
                }
            }
        }

        digits.into_iter().fold(0, |acc, d| acc*10+d)
    }
}

2232 minimize-result-by-adding-parentheses-to-expression/

impl Solution {
pub fn minimize_result(expression: String) -> String {
    let (n1, n2) = expression.split_once("+").unwrap();

    let mut ans_num = i32::MAX/2;
    let mut ans_str = String::new();

    for i in 0..n1.len() {
        for j in 1..=n2.len() {
            let left = if i==0 { 1 } else { n1[..i].parse::<i32>().unwrap() };
            let right = if j==n2.len() { 1 } else { n2[j..].parse::<i32>().unwrap() };
            let mid = n1[i..].parse::<i32>().unwrap() + n2[..j].parse::<i32>().unwrap();

            if left * mid * right < ans_num {
                ans_num = left * mid * right;
                ans_str = format!("{}({}+{}){}", &n1[..i], &n1[i..], &n2[..j], &n2[j..]);
            }
        }
    }

    ans_str.to_string()
}
}

2233 maximum-product-after-k-increments/

impl Solution {
pub fn maximum_product(nums: Vec<i32>, k: i32) -> i32 {
    use std::collections::BinaryHeap;

    let mut heap = BinaryHeap::from(nums.iter().map(|&x| -x).collect::<Vec<_>>());

    for _ in 0..k {
        let peek = heap.pop().unwrap();
        heap.push(peek-1);
    }

    heap.iter().fold(1i64, |acc, &x| acc * -x as i64 % 1000000007) as i32
}
}

2234 maximum-total-beauty-of-the-gardens/

impl Solution {
pub fn maximum_beauty(mut flowers: Vec<i32>, new_flowers: i64, target: i32, full: i32, partial: i32) -> i64 {
    let (full, partial, target) = (full as i64, partial as i64, target as i64);
    let flowers = {
        flowers.sort();
        flowers.iter().map(|&x| x as i64).collect::<Vec<_>>()
    };

    let emptys = flowers.partition_point(|&x| x<target);
    if emptys == 0 {
        return flowers.len() as i64 * full;
    }

    let sum = flowers.iter().scan(0, |sum, &x| {
        *sum += x;
        Some(*sum)
    }).collect::<Vec<_>>();
    let segsum = |left, right| sum[right] - if left==0 { 0 } else { sum[left-1] };

    let mut ans = (flowers.len() - emptys) as i64 * full + flowers[0] * partial;
    for full_bound in (0..=emptys).rev() {
        let full_need = if full_bound==emptys {
            0
        } else {
            target * (emptys-full_bound) as i64 - segsum(full_bound, emptys-1)
        };
        if full_need > new_flowers {
            break;
        }

        if full_bound == 0 {
            ans = ans.max(flowers.len() as i64 * full);
            continue;
        }

        let empty_need = new_flowers - full_need;
        let empty_level = {
            let mut left = flowers[0];
            let mut right = target - 1;
            let mut last_success = left;
            while left <= right {
                let candidate = (right+left)/2;
                let need_approve = flowers[..full_bound].partition_point(|&x| x<candidate);
                if need_approve == 0 || candidate * need_approve as i64 - segsum(0, need_approve-1) <= empty_need {
                    last_success = candidate;
                    left = candidate + 1;
                }
                else {
                    right = candidate - 1;
                }
            }
            last_success
        };

        ans = ans.max((flowers.len()-full_bound) as i64 * full + empty_level * partial);
    }

    ans
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值