下面是 LeetCode 153(寻找旋转排序数组中的最小值) 的 Rust 实现。
Rust 以其内存安全性和零成本抽象著称,下面代码完全遵循 Rust 的语法规范与所有权规则,同时保留了经典的二分查找思路。
Rust 代码实现(LeetCode 标准格式)
impl Solution {
pub fn find_min(nums: Vec) -> i32 {
let mut left = 0;
let mut right = nums.len() - 1;
while left < right { // 防止溢出,等价于 (left + right) / 2 let mid = left + (right - left) / 2; // 如果中间值大于右侧值,说明最小值在右半部分 if nums[mid] > nums[right] { left = mid + 1; } else { // 否则,最小值在左半部分(包括 mid 自身) right = mid; } } // 循环结束时 left == right,即为最小值索引 nums[left] }}
更通用的写法(接受切片
“&[i32]”)
如果你希望在 LeetCode 之外以库函数的方式使用,接受切片是更好的选择:
pub fn find_min(nums: &[i32]) -> i32 {
if nums.is_empty() {
panic!(“数组不能为空”);
}
let mut left = 0; let mut right = nums.len() - 1; while left < right { let mid = left + (right - left) / 2; if nums[mid] > nums[right] { left = mid + 1; } else { right = mid; } } nums[left]}
本地测试示例(
“main” 函数)
fn main() {
let nums1 = vec![3, 4, 5, 1, 2];
println!(“{}”, Solution::find_min(nums1)); // 输出: 1
let nums2 = vec![4, 5, 6, 7, 0, 1, 2]; println!("{}", Solution::find_min(nums2)); // 输出: 0 let nums3 = vec![1, 2, 3, 4, 5]; println!("{}", Solution::find_min(nums3)); // 输出: 1}
Rust 版本要点解析
- 索引类型:Rust 的切片/向量索引必须是
“usize” 类型,
“left”、
“right”、
“mid” 都自然使用
“usize”,避免了有符号/无符号混用的麻烦。 - 防溢出:
“left + (right - left) / 2” 确保了即使
“left” 和
“right” 都很大,也不会发生整数溢出(相比
“(left + right) / 2” 更安全)。 - 无隐式类型转换:Rust 要求严格的类型匹配,
“nums.len()” 返回
“usize”,所以
“right” 也必须是
“usize”,这增强了代码的安全性。 - 性能:与 Java / Python 版本一样,时间复杂度 O(log n),空间复杂度 O(1),且 Rust 没有 GC 开销,运行效率极高。
复杂度分析
- 时间复杂度:O(log n) —— 二分查找,每次范围减半。
- 空间复杂度:O(1) —— 只使用了
“left”、
“right”、
“mid” 三个变量。
如果你还想看 包含重复元素(LeetCode 154)的 Rust 实现,或者想了解 迭代器风格的 Rust 写法,可以继续问我!