为什么要用Rust解题
优点
- 性能强大,但与c++不相上下,由于速度极快,内存利用率高。Rust的解法的运行速度很容易出现为0ms的情况(leecode目前还不支持毫秒级以下精度)。基本上O(n^2)和O(n)都会出现0ms。
- 函数式语法写起来简洁,可读性高。例如:
1 | fn find_short(s: &str) -> u32 { |
- 标准库中栈、队列等结构比较齐全,使用方便。
缺点
- 由于所有权机制导致链表操作极其复杂。
- 要考虑各种数据类型的转换,例如usize, u32, i32之间的转换。
- leecode里有一些题不支持Rust。
小技巧
在确认长度的情况下可以优先分配大小,避免操作过程中因长度不够再次分配。如果长度不是很大,可以直接用固定长的数组,性能比集合要强。
1 | Vec::with_capacity(capacity); |
善用ADT。当涉及到状态判断的时候,可以自定义enum结构,将内存占用降到最低。
1 |
|
Rust的标准库没有随机数,leecode中又不方便引入第三方库,这时可以通过FFI使用c的随机数, 再通过求余约束返回值的范围。
1 | extern "C" { |
排序。sort (归并排序)的排序是稳定的,在不考虑稳定性的情况下可以用sort_unstable (快速排序),可能获取更快的速度和更小的内存占用。对应的还有sort_unstable_by、sort_unstable_by_key。
Rust可以像c/c++一样原地(in-place)修改字符串,实现空间复杂为O(1)的解法。使用into_bytes返回字节数组后用下标访问和修改。
1 | let s = String::from("xxxx"); |
极端情况下可以用c或者汇编来解题。如汉明权重(二进制串中1的个数)。
1 | fn hamming_weight(n: u32) -> u32 { |
考虑浮点数精确度问题,不能直接用 == 判断,而是它们的差小于某一个值。
1 | fn is_integer(float: f32) -> bool { |
数字溢出。防止因数字过大,或者为负数导致的溢出。
1 | let i: u32 = 1; |